From e6e7a168082368e6af4e4171d5a18e3df22a1aee Mon Sep 17 00:00:00 2001 From: Iris Ward Date: Mon, 18 Mar 2019 00:20:36 +0000 Subject: [PATCH] Initial Commit Teawater's May 2018 build, distributed on Discord. --- !Static/Bits.cs | 360 +++++ !Static/Comp.cs | 860 +++++++++++ !Static/SpaceManager.cs | 292 ++++ !Static/globals.cs | 17 + .gitignore | 528 +++++++ App.config | 21 + Controls/ButtonL.cs | 211 +++ Controls/DataNud.cs | 47 + Controls/DataTextbox.cs | 97 ++ Controls/SearchList.cs | 186 +++ Dark Dawn - Copy.cs | 300 ++++ Dark Dawn.cs | 484 ++++++ Editors.Designer.cs | 260 ++++ Editors.cs | 354 +++++ Editors.resx | 120 ++ Form1.Designer.cs | 343 +++++ Form1.cs | 2474 ++++++++++++++++++++++++++++++ Form1.resx | 187 +++ HexEditor.cs | 157 ++ Program.cs | 19 + Properties/AssemblyInfo.cs | 36 + Properties/Resources.Designer.cs | 62 + Properties/Resources.resx | 117 ++ Properties/Settings.Designer.cs | 50 + Properties/Settings.settings | 12 + Sub-editors/!subeditor.cs | 16 + Sub-editors/eClass.cs | 159 ++ Table Manager.cs | 199 +++ VirtList.cs | 210 +++ gsmagic.csproj | 115 ++ 30 files changed, 8293 insertions(+) create mode 100644 !Static/Bits.cs create mode 100644 !Static/Comp.cs create mode 100644 !Static/SpaceManager.cs create mode 100644 !Static/globals.cs create mode 100644 .gitignore create mode 100644 App.config create mode 100644 Controls/ButtonL.cs create mode 100644 Controls/DataNud.cs create mode 100644 Controls/DataTextbox.cs create mode 100644 Controls/SearchList.cs create mode 100644 Dark Dawn - Copy.cs create mode 100644 Dark Dawn.cs create mode 100644 Editors.Designer.cs create mode 100644 Editors.cs create mode 100644 Editors.resx create mode 100644 Form1.Designer.cs create mode 100644 Form1.cs create mode 100644 Form1.resx create mode 100644 HexEditor.cs create mode 100644 Program.cs create mode 100644 Properties/AssemblyInfo.cs create mode 100644 Properties/Resources.Designer.cs create mode 100644 Properties/Resources.resx create mode 100644 Properties/Settings.Designer.cs create mode 100644 Properties/Settings.settings create mode 100644 Sub-editors/!subeditor.cs create mode 100644 Sub-editors/eClass.cs create mode 100644 Table Manager.cs create mode 100644 VirtList.cs create mode 100644 gsmagic.csproj diff --git a/!Static/Bits.cs b/!Static/Bits.cs new file mode 100644 index 0000000..85e99c7 --- /dev/null +++ b/!Static/Bits.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +using System.IO; +namespace gsmagic { + static class Bits { //Mainly used for getting/setting of datatypes, and some parsing of strings. + public static byte[] openFile(string filename) { + try { + return System.IO.File.ReadAllBytes(filename); + //path = filename; + } catch { + return null; + } + } + static public byte[] openFilePart(string filename, int addr, int size) + { + byte[] data = new byte[size]; + using (FileStream a = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { //'StreamReader '( + a.Seek(addr, SeekOrigin.Begin); + a.Read(data, 0, size); + //a.Close() + } + return data; + } + static public byte[] saveFilePart(string filename, int addr, int size, byte[] data) + { + //byte[] data = new byte[size]; + using (FileStream a = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)) + { //'StreamReader '( + a.Seek(addr, SeekOrigin.Begin); + a.Write(data, 0, size); + //a.Close() + } + return data; + } + public static void saveFile(string filename, byte[] buffer) { + System.IO.File.WriteAllBytes(filename, buffer); + //path = filename; + } + static public int getInt16(byte[] buffer, int pos) { //(int addr) + return buffer[pos++] | (buffer[pos] << 8); + } + static public int getInt16(byte[] buffer, uint pos) { //(int addr) + return buffer[pos++] | (buffer[pos] << 8); + } + static public void setInt16(byte[] buffer, int pos, int value) { //(int addr) + buffer[pos++] = (byte)value; + buffer[pos++] = (byte)(value >> 8); + } + static public int getInt32(byte[] buffer, int pos) { //(int addr) + return buffer[pos++] | (buffer[pos++] << 8) | buffer[pos++] << 16 | (buffer[pos] << 24); + } + static public void setInt32(byte[] buffer, int pos, int value) { //(int addr) + buffer[pos++] = (byte)value; + buffer[pos++] = (byte)(value >> 8); + buffer[pos++] = (byte)(value >> 16); + buffer[pos++] = (byte)(value >> 24); + } + static public uint getUInt32(byte[] buffer, int pos) { //(int addr) + return unchecked((uint)(buffer[pos++] | (buffer[pos++] << 8) | buffer[pos++] << 16 | (buffer[pos] << 24))); + } + static public int getBits(byte[] buf, int addr, int numOfBits) + { + int value = 0; + for (int i = 0; i < numOfBits; i += 8) + { + value |= buf[addr++] << i; + } + return value; + } + static public void setBits(byte[] buf, int addr, int numOfBits, int value) + { + for (int j = 0; j < numOfBits; j += 8) + { + buf[addr + (j >> 3)] = (byte)value; + value >>= 8; + } + } + //String functions! + public static string getString(byte[] buffer, int pos, int length) { + System.Text.StringBuilder strbuild = new System.Text.StringBuilder(16); + while (length-- > 0) { + strbuild.Append((char)buffer[pos++]); + } + return strbuild.ToString(); + } + public static string getTextLong(byte[] txt, int index) + { + //textBox1.Text = test.decompStr(test.rom, listBox2.SelectedIndex, 1); + int srcEntry = index; byte p = 0, n = 0; + //while ((Bits.getInt32(txt, srcEntry) != 0) || (srcEntry == 0)) { + StringBuilder str = new StringBuilder(0x200); + int srcPos = 0xC300 + Bits.getInt32(txt, srcEntry * 4); + do + { + n = txt[srcPos++]; + if (n != 0) + { + if (n < 32 || n > 0x7E) + { //~ + str.Append('[' + (n.ToString()) + ']'); + if ((n == 1 || n == 3) && (p < 17 || p > 20) && p != 26 && p != 29) + { + str.Append("\r\n"); + //n = 0; + } + // if argument2 + // { str+='['+string(n)+']'; } + // if argument3 && (n==1 || n==3) && (p<17 || p>20) && p!=26 && p!=29 + // { n=0 } + } + else { str.Append((char)n); } + } + p = n; + } while (n != 0); //Change to while < textArray?-- No, go through offset list instead. + return str.ToString(); + } + //public static byte[] convertStrToRaw() { //Horrible at naming functions. :( + // return null; + //} + public static byte[] textToBytes(string[] items) + { + //Fix this to be similar to Dark Dawn's method? (Similar pointer list, but nothing on the 0xC300.) + byte[] bytes = new byte[0x80000]; + int a = 0; + int b = 0; + for (int i = 0; i < items.Count(); i++) + { + bytes[a++] = (byte)b; + bytes[a++] = (byte)(b >> 8); + bytes[a++] = (byte)(b >> 16); + bytes[a++] = (byte)(b >> 24); + for (int j = 0; j < items[i].Count(); j++) + { + bytes[0xC300 + b++] = (byte)items[i][j]; + //if ((byte)items[i][j] != 0) { MessageBox.Show(((byte)items[i][j]).ToString("x8")); } + } + bytes[b++] = 0; + } + return bytes; + } + public static List numList(int range) + { + List entries = new List(); + for (int i = 0; i < range; i++) + { + entries.Add(i); //= i; + } + return entries; + } + public static List numList(int start, int range) + { + List entries = new List(); + for (int i = 0; i < range; i++) + { + entries.Add(start + i); //= i; + } + return entries; + } + public static string getTextShort(byte[] txt, int index) //Returns one-liners for lists/etc. + { + byte p = 0, n = 0; + //int ind = sortList[index]; + StringBuilder str = new StringBuilder(0x200); + //str.Append((index).ToString().PadLeft(5, ' ') + "|"); + if (index < 0) + return ""; //Blank string in case -1 should be used! + int srcPos = Bits.getInt32(txt, index << 2); + //int srcPos = 0xC300 + Bits.getInt32(txt, index << 2); + if (Bits.getInt32(txt, 0) == 0) + srcPos += 0xC300; + do + { + n = txt[srcPos++]; + if (n != 0) + { + if (n < 32 || n > 0x7E) + { //~ + str.Append('[' + (n.ToString()) + ']'); + if ((n == 1 || n == 3) && (p < 17 || p > 20) && p != 26 && p != 29) { n = 0; } + // if argument2 + // { str+='['+string(n)+']'; } + // if argument3 && (n==1 || n==3) && (p<17 || p>20) && p!=26 && p!=29 + // { n=0 } + } + else { str.Append((char)n); } + } + p = n; + } while (n != 0); //Change to while < textArray?-- No, go through offset list instead. + return str.ToString(); + } + public static string getText2(byte[] buffer, int index) //int address) //Dark Dawn + { + System.Text.StringBuilder strbuild = new StringBuilder(0x200); + //int addr2 = Bits.getInt32(buffer, address) + 0x220B80; + int addr2 = Bits.getInt32(buffer, 0x220B80 + index * 4) + 0x220B80; + int length = 2000; int pos = addr2 & 0xFFFFFF; + //MessageBox.Show(addr2.ToString("x8")); + while (length-- > 0) + { + int c = Bits.getInt16(buffer, pos); pos += 2; + if (c == 0) + break; + if ((c < 0x100) && (c > 0xF)) + strbuild.Append((char)c); + else + strbuild.Append("[" + c.ToString("X4") + "]"); + } + return strbuild.ToString(); + } + public static List getTextMatches(byte[] txt, String str, List items) //, int[] matchList) + { + //String str = textBox2.Text; + byte[] bytes = new byte[0x200]; + int a = 0, b = 0; + while (a < str.Length) + { //Turn text to raw string. (Convert the [#]'s.) + if (str[a] == '[') + { + int num = 0; + while (str[++a] != ']') + { + num = (num * 10) + (byte)(str[a]) - 0x30; + } + a++; + bytes[b++] = (byte)num; + } + else if (((byte)str[a] == 13) && ((byte)str[a + 1] == 10)) + { + a += 2; + } + else + { + bytes[b++] = (byte)str[a++]; + } + } + //b++; //B/c 00 character at end. + int i = 0; + int srcEntry = items[i] * 4; int sortInd = 0; List matchList = new List(); + while (true)//(Bits.getInt32(txt, srcEntry) != 0) || (srcEntry == 0)) + { + if ((srcEntry < 0) || (srcEntry >= 12460)) + { + if (bytes[0] == 0) + { + matchList.Add(i); + } + i++; + if (i >= items.Count()) + break; + srcEntry = items[i] * 4; + continue; + } + int srcPos = 0xC300 + Bits.getInt32(txt, srcEntry); + //int srcPos = 0xC300 + Bits.getInt32(txt, srcEntry * 4); + while (true) + { + int n = 0;//int n = txt[srcPos++]; + while ((txt[srcPos + n] != 0) && (txt[srcPos + n] != bytes[0])) + { + srcPos++; + } + while ((bytes[n] != 0) && (txt[srcPos + n] == bytes[n])) + { //(bytes[n] != 0) or check 0 on other array. + n++; + } + if (bytes[n] == 0) { matchList.Add(i); break; } //add this entry. + if (txt[srcPos + n] == 0) { break; }; + srcPos++; + //return; + } + i++; + if (i >= items.Count()) + break; + srcEntry = items[i] * 4; + } + return matchList; + } + public static List getTextMatches2(byte[] txt, String str, List items) //, int[] matchList) + { + //String str = textBox2.Text; + byte[] bytes = new byte[0x200]; + int a = 0, b = 0; + while (a < str.Length) + { //Turn text to raw string. (Convert the [#]'s.) + if (str[a] == '[') + { + int num = 0; + while (str[++a] != ']') + { + int n = str[a]; + if ((n >= 0x41) && (n <= 0x46)) + num = (num * 16) + 10 + (n - 0x41); + else if ((n >= 0x61) && (n <= 0x66)) + num = (num * 16) + 10 + (n - 0x61); + else + num = (num * 16) + (byte)(str[a]) - 0x30; + } + a++; + bytes[b++] = (byte)num; + } + else if (((byte)str[a] == 13) && ((byte)str[a + 1] == 10)) + { + a += 2; + } + else + { + bytes[b++] = (byte)str[a++]; + } + } + //b++; //B/c 00 character at end. + int i = 0; + int srcEntry = items[i] * 4; int sortInd = 0; List matchList = new List(); + while (true)//(Bits.getInt32(txt, srcEntry) != 0) || (srcEntry == 0)) + { + if ((srcEntry < 0) || (srcEntry >= 12460)) + { + if (bytes[0] == 0) + { + matchList.Add(i); + } + i++; + if (i >= items.Count()) + break; + srcEntry = items[i] * 4; + continue; + } + int srcPos = Bits.getInt32(txt, 0x220B80 + srcEntry) + 0x220B80; + //int srcPos = 0xC300 + Bits.getInt32(txt, srcEntry); + //int srcPos = 0xC300 + Bits.getInt32(txt, srcEntry * 4); + while (true) + { + int n = 0;//int n = txt[srcPos++]; + while ((txt[srcPos + n] != 0) && (txt[srcPos + n] != bytes[0])) + { + srcPos++; + } + while ((bytes[n] != 0) && (txt[srcPos + n] == bytes[n])) + { //(bytes[n] != 0) or check 0 on other array. + n++; + } + if (bytes[n] == 0) { matchList.Add(i); break; } //add this entry. + if (txt[srcPos + n] == 0) { break; }; + srcPos++; + //return; + } + i++; + if (i >= items.Count()) + break; + srcEntry = items[i] * 4; + } + return matchList; + } + } +} diff --git a/!Static/Comp.cs b/!Static/Comp.cs new file mode 100644 index 0000000..595d3b3 --- /dev/null +++ b/!Static/Comp.cs @@ -0,0 +1,860 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace gsmagic { + static class Comp { + //partial class Form1 { //Partial because I don't want to duplicate "static" across all functions. + static public int[] decompress(byte[] src, int srcPos, byte[] des, int desPos) { + return decompressf(src, srcPos + 1, des, desPos, src[srcPos]); + } + static public int[] decompressf(byte[] src, int srcPos, byte[] des, int desPos, int format) { + int desStart = desPos; //Needed for when Distance is variable bits. + //byte[] des = new byte[0x10000]; //Largest size ever needed. + //public byte[] decompress(byte[] src, int srcPos, int desPos) { + // byte[] des = new byte[0x10000]; //Largest size ever needed. + int bits, readcount, i, _byte; //offset; + uint n; ulong z = 0xFEDCBA9876543210; + //int format = src[srcPos++]; + if (format == 0 || format == 2) { + bits = 0; + int bitnum = 0; + if ((srcPos & 1) == 1) { bits = src[srcPos++]; bitnum = 8; } //Optional + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + while (true) { + readcount = 0; + if ((bits & 1) == 1) { + bits >>= 1; bitnum -= 1; + if (format == 0) { //Format 0: Constant + des[desPos++] = (byte)bits; bits >>= 8; bitnum -= 8; + } else { //Format 2: Recent Priority + if ((bits & 1) == 1) { + i = 2; bits >>= 1; bitnum -= 1; + } else if ((bits & 2) == 2) { + i = 3; bits >>= 2; bitnum -= 2; + } else { + i = 4; bits >>= 2; bitnum -= 2; + } + for (int offset = 0; offset < 8; offset += 4) { + _byte = (bits & ((1 << i) - 1)); bits >>= i; bitnum -= i; //Read from compressed data. + n = (uint)(0xF & (z >> (int)(_byte << 2))); //Get selected value. + if (_byte != 0xF) { // Check 0xF because <<0x40 does nothing. (ex: no-op?) + z = (z & (unchecked((ulong)-1) << ((_byte + 1) << 2))) //Keep tail end. + | ((z & ((((ulong)1) << (_byte << 2)) - 1)) << 4) //Close gap. + | n; //Put selected value in front. + } else { z = (z << 4) | n; } + des[desPos] |= (byte)(n << offset); //Write decompressed 4-bit. + } + desPos++; + } + if (bitnum < 0) { + bitnum += 16; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + } + } else if ((bits & 3) == 0) { //Format 0 & 2: Distance Length: Length + readcount = 2; bits >>= 2; bitnum -= 2; + } else if ((bits & 7) == 2) { + readcount = 3; bits >>= 3; bitnum -= 3; + } else if ((bits & 0xF) == 6) { + readcount = 4; bits >>= 4; bitnum -= 4; + } else if ((bits & 0x1F) == 0xE) { + readcount = 5; bits >>= 5; bitnum -= 5; + } else if ((bits & 0x7F) == 0x1E) { + readcount = 6; bits >>= 7; bitnum -= 7; + } else if ((bits & 0x7F) == 0x5E) { + readcount = 7; bits >>= 7; bitnum -= 7; + } else if ((bits & 0x3F) == 0x3E) { + readcount = 7 + ((bits >> 6) & 3); bits >>= 8; bitnum -= 8; + if (readcount == 7) { + readcount = 10 + (bits & 127); bits >>= 7; bitnum -= 7; + if (readcount == 10) { return new int[] { srcPos, desPos }; } // des; } + } + } + if (bitnum < 0) { + bitnum += 16; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + } + if (readcount != 0) { //Format 0 & 2: Distance Length: Distance + uint offset = 0; + if ((bits & 1) == 0) { //Long Distance - 0~12-bit distance + bits >>= 1; bitnum -= 1; + offset = (uint)desPos - (uint)desStart - 33; + _byte = 12; + while (offset < (1 << (_byte - 1))) { + _byte -= 1; + } + offset = (uint)(32 + (bits & ((1 << _byte) - 1))); bits >>= _byte; bitnum -= _byte; + } else { //Short Distance - 5-bit distance + bits >>= 1; bitnum -= 1; + offset = (uint)(bits & 31); bits >>= 5; bitnum -= 5; + } + if (bitnum < 0) { + bitnum += 16; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + } + //if (desPos < offset) { return null; } + while (readcount-- > 0) { + des[desPos] = des[desPos - offset - 1]; desPos++; + } + } + } + } else { //Format 1 + while (true) { + bits = src[srcPos++]; + for (int j = 0x80; j > 0; j >>= 1) { + if ((bits & j) == 0) { + des[desPos++] = src[srcPos++]; + } else { + readcount = src[srcPos++]; + int offset = src[srcPos++] | ((readcount & 0xF0) << 4); + readcount = readcount & 15; + if (readcount == 0) { + if (offset == 0) { return new int[] { srcPos, desPos }; } // des; } + readcount = src[srcPos++] + 16; + } + //if (desPos < offset) { return null; } + while (readcount-- >= 0) { + des[desPos] = des[desPos - offset]; desPos++; + } + } + } + } + } + //return des; + } + static public int[] compressFormat1(byte[] src, int srcPos, byte[] des, int desPos) { + int dst = 0, len = 0; + while (true) + { + int fPos = desPos++; + for (int a = 0x80; a != 0; a >>= 1) + { + if (srcPos >= src.Length) + { + des[fPos] |= (byte)a; + des[desPos++] = 0; + des[desPos++] = 0; + return new int[] { srcPos, desPos }; + //return desPos; + } + //Find best Distance Length. (If current=Constant) + int sp2 = srcPos + 1, dst2 = 0, len2 = 0, maxLen2 = Math.Min(0x110, src.Length - sp2); + int dictEnd2 = Math.Max(0, sp2 - 0xFFF); + for (int i = sp2 - 1; i >= dictEnd2; i--) + { + int j = 0; + while (j < maxLen2) + { + if (src[sp2 + j] != src[i + j]) + break; + j++; + } + if (j > len2) + { + dst2 = i; len2 = j; + if (j >= 0x10F) + break; + } + } + //Find best Distance Length. (If current=Best Distance Length) + int sp3 = srcPos + len, dst3 = 0, len3 = 0, maxLen3 = Math.Min(0x110, src.Length - sp3); + int dictEnd3 = Math.Max(0, sp3 - 0xFFF); + for (int i = sp3 - 1; i >= dictEnd3; i--) + { + int j = 0; + while (j < maxLen3) + { + if (src[sp3 + j] != src[i + j]) + break; + j++; + } + if (j > len3) + { + dst3 = i; len3 = j; + if (j >= 0x10F) + break; + } + } + + if (len2 == 0) + len2 = 1; + if (len3 == 0) + len3 = 1; + if ((len == len2) && (len3 == 1)) + { + } + else + if ((1 + len2) >= (len + len3)) //Constant is better in this condition. + len = 1; + + if (len < 2) + { //Insert Constant into compression. + des[desPos++] = src[srcPos++]; + dst = dst2; len = len2; + } + else + { //Insert Distance Length into compression. + des[fPos] |= (byte)a; + if (len <= 16) + { + des[desPos++] = (byte)((((srcPos - dst) >> 8) << 4) | (len - 1)); + des[desPos++] = (byte)((srcPos - dst) & 0xFF); + } + else + { + des[desPos++] = (byte)(((srcPos - dst) >> 8) << 4); + des[desPos++] = (byte)((srcPos - dst) & 0xFF); + des[desPos++] = (byte)(len - 16 - 1); + } + srcPos += len; + dst = dst3; len = len3; + } + } + } + } + static public byte[] decompress16All(byte[] src, int srcPos) { + int entries = 0; + int srcPos2 = srcPos; + while (Bits.getInt32(src, srcPos2) != -1) { + entries++; srcPos2 += 4; + } + + //Console.WriteLine(srcPos2.ToString("x8") + " " + entries);//Bits.getInt32(src,0x4f124)); + byte[] des = new byte[entries * 0x100]; + for (int desPos = 0; desPos < des.Length; desPos += 0x100) { + decompress16(src, Bits.getInt32(src, srcPos) & 0x1ffffff, des, desPos); srcPos += 4; + } + return des; + } + static public void decompress16(byte[] src, int srcPos, byte[] des, int desPos) { + //byte[] des = new byte[0x4000]; + int bits = 0, i = 0, bitnum = 0; + uint n; ulong z = 0xFEDCBA9876543210; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + while (true) { + if ((bits & 0x1) == 0x0) { + i = 0; bits >>= 1; bitnum -= 1; + } else if ((bits & 0x7) == 0x1) { + i = 1; bits >>= 3; bitnum -= 3; + } else if ((bits & 0xF) == 0x5) { + i = 2; bits >>= 4; bitnum -= 4; + } else if ((bits & 0xF) == 0xD) { + i = 3; bits >>= 4; bitnum -= 4; + } else if ((bits & 0xF) == 0x3) { + i = 4; bits >>= 4; bitnum -= 4; + } else if ((bits & 0xF) == 0xB) { + i = 5; bits >>= 4; bitnum -= 4; + } else if ((bits & 0xF) == 0x7) { + i = 6; bits >>= 4; bitnum -= 4; + } else if ((bits & 0x3F) == 0xF) { + i = 7; bits >>= 6; bitnum -= 6; + } else if ((bits & 0x3F) == 0x2F) { + i = 8; bits >>= 6; bitnum -= 6; + } else if ((bits & 0x3F) == 0x1F) { + i = 9; bits >>= 6; bitnum -= 6; + } else if ((bits & 0xFF) == 0x3F) { + i = 10; bits >>= 8; bitnum -= 8; + } else if ((bits & 0xFF) == 0xBF) { + i = 11; bits >>= 8; bitnum -= 8; + } else if ((bits & 0xFF) == 0x7F) { + i = 12; bits >>= 8; bitnum -= 8; + } else if ((bits & 0x3FF) == 0xFF) { + i = 13; bits >>= 10; bitnum -= 10; + } else if ((bits & 0x3FF) == 0x2FF) { + i = 14; bits >>= 10; bitnum -= 10; + } else if ((bits & 0x3FF) == 0x1FF) { + i = 15; bits >>= 10; bitnum -= 10; + } else if ((bits & 0x3FF) == 0x3FF) { + return;// des; + } + n = (uint)(0xF & (z >> (int)(i << 2))); //Get selected value. + if (i != 0xF) { // Check 0xF because <<0x40 does nothing. (ex: no-op?) + z = (z & (unchecked((ulong)-1) << ((i + 1) << 2))) //Keep tail end. + | ((z & ((((ulong)1) << (i << 2)) - 1)) << 4) //Close gap. + | n; //Put selected value in front. + } else { z = (z << 4) | n; } + des[desPos++] = (byte)n; //Write decompressed 4-bit. + + if (bitnum < 0) { + bitnum += 16; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + } + } + } + static int[] bitTable = {0x1, 0x0, 0x3, 0x1, 0x4, 0x5, 0x4, 0xD, + 0x4, 0x3, 0x4, 0xB, 0x4, 0x7, 0x6, 0xF, + 0x6, 0x2F, 0x6, 0x1F, 0x8, 0x3F, 0x8, 0xBF, + 0x8, 0x7F, 0xA, 0xFF, 0xA, 0x2FF, 0xA, 0x1FF, + 0xA, 0x3FF}; + static void compress16(byte[] src, int srcPos, byte[] des, int desPos) { //Not tested. + int bitnum = 0, bits = 0, i = 0; + uint n = 0; ulong z = 0xFEDCBA9876543210; + while (srcPos < src.Length) { //Length may be changed? + while ((((z >> i) & 0xF) != src[srcPos])) { + i += 4; + } + bits = bits | (bitTable[(i >> 1) + 1] << bitnum); bitnum += bitTable[i >> 1]; + while (bitnum >= 8) { + des[desPos] = (byte)bits; bits >>= 8; bitnum -= 8; + } + + n = (uint)(0xF & (z >> (int)i)); //Get selected value. + if (i != 0x3C) { // Check 0xF because <<0x40 does nothing. (ex: no-op?) + z = (z & (unchecked((ulong)-1) << (i + 4))) //Keep tail end. + | ((z & ((((ulong)1) << i) - 1)) << 4) //Close gap. + | n; //Put selected value in front. + } else { z = (z << 4) | n; } + srcPos++; + } + bits = bits | (bitTable[0x21] << bitnum); bitnum += bitTable[0x20]; + while (bitnum > 0) { + des[desPos] = (byte)bits; bits >>= 8; bitnum -= 8; + } + } + static byte[] decompBtlBG(byte[] src, int srcPos) { + byte[] des = new byte[0x8000]; int desPos = 0; + int bits = 0, i = 0x60, bitnum = 0; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + for (int j = 0; j < 0x7800; j++) { + switch (bits & 7) { + case 0: + case 4: + bits >>= 2; bitnum -= 2; + break; + case 1: + bits >>= 3; bitnum -= 3; + i += 1 + (bits & 1); bits >>= 1; bitnum -= 1; + break; + case 2: + bits >>= 3; bitnum -= 3; + if ((bits & 1) == 0) { + bits >>= 1; bitnum -= 1; + i += 11 + (bits & 0xF); bits >>= 4; bitnum -= 4; + } else { + bits >>= 1; bitnum -= 1; + i -= 11 + (bits & 0xF); bits >>= 4; bitnum -= 4; + } + break; + case 3: + bits >>= 3; bitnum -= 3; + i += 3 + (bits & 7); bits >>= 3; bitnum -= 3; + break; + case 5: + bits >>= 3; bitnum -= 3; + i -= 1 + (bits & 1); bits >>= 1; bitnum -= 1; + break; + case 6: + bits >>= 3; bitnum -= 3; + i = 0x60 + (bits & 0x7F); bits >>= 7; bitnum -= 7; + break; + case 7: + bits >>= 3; bitnum -= 3; + i -= 3 + (bits & 7); bits >>= 3; bitnum -= 3; + break; + } + des[desPos++] = (byte)i; + if (bitnum < 0) { + bitnum += 16; + bits += ((int)src[srcPos++] << bitnum) + ((int)src[srcPos++] << (8 + bitnum)); + } + } + return des; + } + static public byte[] decompText(byte[] src) { //, int srcInd) { // int srcPos) { + //return decompTextOld(src); + DateTime c = DateTime.Now; + int[] bitcode = new int[0x10000]; + byte[] bitLen = new byte[0x10000]; + short[] bitChar = new short[0x10000]; + //Scan char data to generate data for faster decompression than old method. + int asmpchar = Bits.getInt32(src, 0x38578) - 0x8000000; + int asmptext = Bits.getInt32(src, 0x385DC) - 0x8000000; + int chardata = Bits.getInt32(src, asmpchar) - 0x08000000; + int charpntrs = Bits.getInt32(src, asmpchar + 4) - 0x08000000; + for (int char1 = 0; char1 < 0x100; char1++) { + if (charpntrs == asmpchar) { break; } + if (Bits.getInt16(src, charpntrs) == 0x8000) { charpntrs += 2; continue; } + int charTree = (chardata + Bits.getInt16(src, charpntrs)) << 3; charpntrs += 2; + int charSlot = charTree - 12; + byte bits = 0; int bitC = 0; int entry = (char1 << 8); + do { + while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { bits++; } + bitChar[entry] = (short)((Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF); charSlot -= 12; + bitLen[entry] = bits; if (bits >= 24) { return decompTextOld(src); } + bitcode[entry] = bitC; + while (((bitC >> (bits - 1)) & 1) == 1) { bits -= 1; bitC ^= 1 << bits; } + bitC |= 1 << (bits - 1); + entry += 1; + } while (bits > 0); + } + //Console.WriteLine(DateTime.Now - c); + //c = DateTime.Now; + int textTree = 0, textLenAddr = 0; + byte[] des = new byte[0x800000]; int desEntry = 0, desPos = 0xC300; + for (int srcI = 0; srcI < 12461; srcI++) { + Bits.setInt32(des, desEntry, desPos - 0xC300); desEntry += 4; + int srcInd = srcI; + if ((srcInd & 0xFF) == 0) { + textTree = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3)) - 0x08000000; + textLenAddr = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3) + 4) - 0x08000000; + } else { + int cLen; + do { + cLen = src[textLenAddr++]; + textTree += cLen; + } while (cLen == 0xFF); + } + int initChar = 0, bitnum = 0, val = 0, textTree2 = textTree; + do { + while (bitnum < 24) { val |= (int)src[textTree2++] << bitnum; bitnum += 8; } + int entry = initChar << 8; + while ((val & ((1 << bitLen[entry]) - 1)) != bitcode[entry]) { entry++; } + initChar = bitChar[entry]; val >>= bitLen[entry]; bitnum -= bitLen[entry]; + des[desPos++] = (byte)initChar; + //if (desPos >= 0x10000) { break; } + } while (initChar != 0); + } + Console.WriteLine(DateTime.Now - c + " (Text Decompression)"); + return des; + } + static public byte[] decompTextOld(byte[] src) { + DateTime c = DateTime.Now; + int asmpchar = Bits.getInt32(src, 0x38578) - 0x8000000; + int asmptext = Bits.getInt32(src, 0x385DC) - 0x8000000; + int chardata = Bits.getInt32(src, asmpchar) - 0x08000000; + int charpntrs = Bits.getInt32(src, asmpchar + 4) - 0x08000000; + byte[] des = new byte[0x800000]; int desEntry = 0, desPos = 0xC300; + for (int srcI = 0; srcI < 12461; srcI++) { + Bits.setInt32(des, desEntry, desPos - 0xC300); desEntry += 4; + int srcInd = srcI; + + int textTree = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3)) - 0x08000000; + int textLenAddr = Bits.getInt32(src, asmptext + ((srcInd >> 8) << 3) + 4) - 0x08000000; + srcInd &= 0xFF; + while (srcInd-- != 0) { + int cLen; + do { + cLen = src[textLenAddr++]; + textTree += cLen; + } while (cLen == 0xFF); + } + int initChar = 0; + + textTree <<= 3; + do { + int charTree = (chardata + Bits.getInt16(src, charpntrs + (initChar << 1))) << 3; + int charSlot = charTree - 12; + while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + if (((src[textTree >> 3] >> (textTree++ & 7)) & 1) == 1) { + int depth = 0; + while (depth >= 0) { + while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + depth++; + } + charSlot -= 12; + depth--; + } + } + } + initChar = (Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF; + des[desPos++] = (byte)initChar; + //do { + // n=getNextCharacter(argument0) + // if n!=0 { + // if (n<32 || n>ord('~')) { + // if argument2 + // { str+='['+string(n)+']'; } + // if argument3 && (n==1 || n==3) && (p<17 || p>20) && p!=26 && p!=29 + // { n=0 } + // } else { str+=chr(n); } + // } + // p=n + //} until n=0 + } while (initChar != 0); + } + Console.WriteLine(DateTime.Now - c + " (Old Text Decompression)"); + return des; + } + //short[] freq = new short[0x10000]; //We need to know how often each character combination occurs to determine best bit amounts. + //short[] clen = new short[0x100]; //How many chars each char has associated with it. + //short[] clst = new short[0x10000]; //Char list in the order they appear in the text. + static public void comptext(byte[] src, byte[] dest) { + DateTime c = DateTime.Now;//.Ticks; + //Welcome to my Huffman Hamburger! (Scan text, do complex char tables, compress text.) + //Scan text to generate frequency table. + ushort char1 = 0, char2 = 0; + ushort[] freq = new ushort[0x10000]; //We need to know how often each character combination occurs to determine best bit amounts. + ushort[] clen = new ushort[0x100]; //How many chars each char has associated with it. + ushort[] clst = new ushort[0x10000]; //Char list in the order they appear in the text. + int srcEntry = 0; + while ((Bits.getInt32(src, srcEntry) != 0) || (srcEntry == 0)) { //Set up frequency table and char list (in order displayed in text.) + int srcPos = 0xC300 + Bits.getInt32(src, srcEntry); + do { + char2 = src[srcPos++]; + if (freq[char1 * 0x100 + char2]++ == 0) { + clst[char1 * 0x100 + clen[char1]++] = char2; //clen[char1]++;// += 1; + } + //freq[char1 * 0x100 + char2] += 1; + char1 = char2; + } while (char1 != 0); //Change to while < textArray?-- No, go through offset list instead. + srcEntry += 4; + } + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/clst.dmp", Array.ConvertAll(clst, delegate(short item) { return (byte)item; })); + byte[] bitLen = new byte[0x10000]; //int[] bitLen = new int[0x10000]; + int[] bitCode = new int[0x10000]; + int addr2 = 0, chrptlen = 0; + byte[] chrTbl = new byte[0x8000]; + byte[] chrPtrs = new byte[0x200]; + for (int c1 = 0; c1 < 0x100; c1++) { + if (clen[c1] == 0) { chrPtrs[(c1 << 1) + 1] = 0x80; continue; } + chrptlen = (c1 + 1) << 1; + //if (c1 > 5) { continue; } //For testing. + //Sort chars by symbol frequency (simple) + //See https://en.wikipedia.org/wiki/Sorting_algorithm - Use a Stable one so same-freq chars stay in order. + //I pick simple Insertion Sort for now, since we are dealing with small sets. (https://en.wikipedia.org/wiki/Insertion_sort) + for (int i = 1; i < clen[c1]; i++) { + ushort x = clst[(c1 << 8) + i]; + int j = i; + while ((j > 0) && (freq[(c1 << 8) + clst[(c1 << 8) + j - 1]] > freq[(c1 << 8) + x])) { + clst[(c1 << 8) + j] = clst[(c1 << 8) + j - 1]; + j = j - 1; + } + clst[(c1 << 8) + j] = x; + } + //Sort chars by node frequency (More advanced) + int[] symbSort = new int[0x100]; //Basically points to chars in order to be displayed in data. + int[] symbBits = new int[0x100]; + int[] nodeHead = new int[0x100]; + int[] nodeTail = new int[0x100]; + int[] nodeFreq = new int[0x100]; nodeFreq[0] = 0x7FFFFFFF; nodeFreq[1] = 0x7FFFFFFF; //Ensure unused/node2 when there is none. + int nodeA = 0, nodeI = 0, symbI = 0; + if (clen[c1] > 1) { + while ((symbI < clen[c1]) || (nodeA < nodeI - 1)) { + int symfreq1 = freq[(c1 << 8) + clst[(c1 << 8) + symbI]]; + int symfreq2 = freq[(c1 << 8) + clst[(c1 << 8) + symbI + 1]]; + if ((symbI + 1 < clen[c1]) && (symfreq2 <= nodeFreq[nodeA])) { //Symbol - Symbol + symbSort[symbI] = symbI + 1; + nodeHead[nodeI] = symbI; nodeTail[nodeI] = symbI + 1; + nodeFreq[nodeI] = symfreq1 + symfreq2; + symbI += 2; + } else if ((symbI < clen[c1]) && (symfreq1 <= nodeFreq[nodeA])) { // Symbol - Node + symbSort[symbI] = nodeHead[nodeA]; + nodeHead[nodeI] = symbI; nodeTail[nodeI] = nodeTail[nodeA]; + nodeFreq[nodeI] = symfreq1 + nodeFreq[nodeA]; + symbI++; nodeA++; + } else if ((nodeA < nodeI - 1) && ((nodeFreq[nodeA + 1] < symfreq1) || ((symbI >= clen[c1])))) { // Node - Node + symbSort[nodeTail[nodeA]] = nodeHead[nodeA + 1]; + nodeHead[nodeI] = nodeHead[nodeA]; nodeTail[nodeI] = nodeTail[nodeA + 1]; + nodeFreq[nodeI] = nodeFreq[nodeA] + nodeFreq[nodeA + 1]; + nodeA += 2; + } else if (nodeFreq[nodeA] < symfreq1) { // Node - Symbol + symbSort[nodeTail[nodeA]] = symbI; + nodeHead[nodeI] = nodeHead[nodeA]; nodeTail[nodeI] = symbI; + nodeFreq[nodeI] = nodeFreq[nodeA] + symfreq1; + symbI++; nodeA++; + } + symbBits[clst[(c1 << 8) + nodeHead[nodeI++]]] += 1; + } + } + addr2 += (((clen[c1] * 12) + 4) & -8); + chrPtrs[(c1 << 1)] = (byte)(addr2 >> 3); + chrPtrs[(c1 << 1) + 1] = (byte)(addr2 >> 11); + int addr1 = addr2 - 12; + byte bitsL = 0; + //int val = 0; + //int bitnum = (clen[c1] & 1) * 4; + int bitC = 0; + for (int n = clen[c1]; n > 0; n--) { + //List chars + chrTbl[(addr1 >> 3)] |= (byte)(clst[(c1 << 8) + nodeHead[nodeA]] << (addr1 & 7)); + chrTbl[(addr1 >> 3) + 1] |= (byte)(clst[(c1 << 8) + nodeHead[nodeA]] >> (8 - (addr1 & 7))); + addr1 -= 12; + //val |= clst[(c1 << 8) + nodeHead[nodeA]] << bitnum; bitnum += 12; + //while (bitnum >= 8) { + // chrTbl[addr1++] = (byte)val; bitnum -= 8; + //} + //List the char's tree/flags + addr2 += symbBits[clst[(c1 << 8) + nodeHead[nodeA]]]; + chrTbl[addr2 >> 3] |= (byte)(1 << (addr2++ & 7)); + //Calculate bit lengths for bit code. + bitsL += (byte)symbBits[clst[(c1 << 8) + nodeHead[nodeA]]]; + //bitLen[clst[(c1 << 8) + nodeHead[nodeA]]] = bitsL; + bitLen[(c1 << 8) + clst[(c1 << 8) + nodeHead[nodeA]]] = bitsL; + //if (symbBits[clst[(c1 << 8) + nodeHead[nodeA]]] == 0) { bitsL -= 1; } + //if (c1 == 0) { Console.WriteLine(bitC.ToString("X8") + " " + bitsL.ToString("X8") + " " + (char)clst[(c1 << 8) + nodeHead[nodeA]]); } + //Generate bitCode table. + bitCode[(c1 << 8) + clst[(c1 << 8) + nodeHead[nodeA]]] = bitC; + while (((bitC >> (bitsL - 1)) & 1) == 1) { bitsL -= 1; bitC ^= 1 << bitsL; } + bitC |= 1 << (bitsL - 1); + + nodeHead[nodeA] = symbSort[nodeHead[nodeA]]; + } + addr2 = (addr2 + 8) & -8; + //Console.WriteLine("\nLetter by node order"); + //for (int zz = 0; zz < clen[c1]; zz++) { + // Console.Write(clst[(c1 << 8) + nodeHead[nodeA]].ToString("X4") + " "); + // //Console.Write(symbBits[clst[(c1 << 8) + nodeHead[nodeA]]].ToString("X4") + " "); + // nodeHead[nodeA] = symbSort[nodeHead[nodeA]]; + //} + //Console.WriteLine("\nsymbSort"); + //for (int zz = 0; zz < clen[c1]; zz++) { + // Console.Write(symbSort[zz].ToString("X4") + " "); + //} + } + //Finally compress the text. + int val = 0, bitnum = 0, ctAddr = 0, cstrstart = 0; + byte[] cText = new byte[src.Length]; + byte[] txtref1 = new byte[0x200]; int tr1Addr = 0; + byte[] txtref2 = new byte[0x8000]; int tr2Addr = 0; + srcEntry = 0; char1 = 0; + while ((Bits.getInt32(src, srcEntry) != 0) || (srcEntry == 0)) { + if ((srcEntry & 0x3FC) == 0) { + Bits.setInt32(txtref1, tr1Addr, ctAddr); tr1Addr += 4; + Bits.setInt32(txtref1, tr1Addr, tr2Addr); tr1Addr += 4; + } + cstrstart = ctAddr; + int srcPos = 0xC300 + Bits.getInt32(src, srcEntry); val = 0; + do { + char2 = src[srcPos++]; + val |= bitCode[(char1 << 8) + char2] << bitnum; + bitnum += bitLen[(char1 << 8) + char2]; + while (bitnum >= 8) { + cText[ctAddr++] = (byte)val; val >>= 8; bitnum -= 8; + } + //if (freq[char1 * 0x100 + char2]++ == 0) { + // clst[char1 * 0x100 + clen[char1]++] = char2; //clen[char1]++;// += 1; + //} + //freq[char1 * 0x100 + char2] += 1; + //if (srcEntry == 0) { Console.WriteLine(bitCode[(char1 << 8) + char2].ToString("X8") + " " + bitLen[(char1 << 8) + char2].ToString("X8")); } + char1 = char2; + } while (char1 != 0); //Change to while < textArray?-- No, go through offset list instead. + srcEntry += 4; if (bitnum != 0) { cText[ctAddr++] = (byte)val; bitnum = 0; } + while ((ctAddr - cstrstart) > 0xFE) { txtref2[tr2Addr++] = 0xFF; cstrstart += 0xFF; } + txtref2[tr2Addr++] = (byte)(ctAddr - cstrstart); //cstrstart = ctAddr; + } + //Now insert everything into the ROM. + int insAddr = 0xFA0000; + int loc1 = insAddr; + Array.Copy(chrTbl, 0, dest, insAddr, addr2 >> 3); insAddr += addr2 >> 3; + insAddr = (insAddr + 1) & -2; + int loc2 = insAddr; + Array.Copy(chrPtrs, 0, dest, insAddr, chrptlen); insAddr += chrptlen; + Bits.setInt32(dest, 0x38578, 0x08000000 + insAddr); + Bits.setInt32(dest, insAddr, 0x08000000 + loc1); insAddr += 4; + Bits.setInt32(dest, insAddr, 0x08000000 + loc2); insAddr += 4; + loc1 = insAddr; + Array.Copy(cText, 0, dest, insAddr, ctAddr); insAddr += ctAddr; + loc2 = insAddr; + Array.Copy(txtref2, 0, dest, insAddr, tr2Addr); insAddr += tr2Addr; + insAddr = (insAddr + 3) & -4; + Bits.setInt32(dest, 0x385DC, 0x08000000 + insAddr); + for (int a = 0; a < tr1Addr; a += 8) { + Bits.setInt32(dest, insAddr + a, 0x08000000 + Bits.getInt32(txtref1, a) + loc1); + Bits.setInt32(dest, insAddr + a + 4, 0x08000000 + Bits.getInt32(txtref1, a + 4) + loc2); + } + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/txtromtest.gba", dest); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/txtref1.dmp", txtref1); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/txtref2.dmp", txtref2); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/cText.dmp", cText); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/chrPtrs.dmp", chrPtrs); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/chrTbl.dmp", chrTbl); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/bitLen.dmp", bitLen); + //DateTime c = DateTime.Now;//.Ticks; + Console.WriteLine((DateTime.Now - c).ToString()); + } + ////--Trash below? + ////Make list that points from least frequent char to most frequent char. + //int[] cltg = new int[0x10000]; //short[] cltg = new short[0x10000]; //Chars least to greatest - Swap to 0x200(?)(Esp. if contains node info) bytes and use same memory for all chars. (Since don't need them simutaneously.) + ////for (int charScan = 0; charScan < 0x100; charScan++) { + // for (int j = 0; j < 0x0100; j++) { + // if (clen[j] <= 1) { continue; } + // int wgtMin = 1, wgt1 = 0xffff, wgt2 = 0xffff;//, wfInd = 0; + // wgt1 = getWgt(j, ref wgtMin); + // wgt2 = getWgt(j, ref wgtMin); + // int ApdInd = 0, nodeInd = 0, nodeFreq = 0; + // //Auto: wgt1 <= wgt2 ; wgts ? nodeFreqs ; NodeFreq <= NodeFreq2 + // cltg[ApdInd++] = wgt1; + // cltg[ApdInd++] = wgt2; + // wgt1 = getWgt(j, ref wgtMin); + // wgt2 = getWgt(j, ref wgtMin); + // //nodeInd = 0; + // nodeFreq = cltg[nodeInd++] + cltg[nodeInd++]; + // int nodeFreq2 = 0xffff; // cltg[nodeInd++] + cltg[nodeInd++]; + // for (int loops = 0; loops < clen[j] - 3; loops++) { //-1=default + -2=already put in 2 freqs. + // if (wgt2 <= nodeFreq) { + // cltg[ApdInd++] = wgt1; + // cltg[ApdInd++] = wgt2; + // wgt1 = getWgt(j, ref wgtMin); + // wgt2 = getWgt(j, ref wgtMin); + // if (nodeFreq2 == 0xFFFF) { + // nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // } + // } else if (wgt1 <= nodeFreq) { + // cltg[ApdInd++] = wgt1; + // cltg[ApdInd++] = nodeFreq; + // wgt1 = wgt2; wgt2 = getWgt(j, ref wgtMin); + // if (nodeFreq2 == 0xFFFF) { + // nodeFreq = cltg[nodeInd++] + cltg[nodeInd++]; + // } else { + // nodeFreq = nodeFreq2; + // nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // } + // } else if (nodeFreq2 < wgt1) { + // cltg[ApdInd++] = nodeFreq; + // cltg[ApdInd++] = nodeFreq2; + // //if (nodeFreq2 != 0xFFFF) { nodeFreq = nodeFreq2; } + // nodeFreq = cltg[nodeInd++] + cltg[nodeInd++]; + // if (nodeInd < ApdInd) { + // nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // } else { + // nodeFreq2 = 0xFFFF; + // } + // //nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // } else if (nodeFreq < wgt1) { //(nodeFreq < wgt1) + // cltg[ApdInd++] = nodeFreq; + // cltg[ApdInd++] = wgt1; + // if (nodeFreq2 == 0xFFFF) { + // nodeFreq = cltg[nodeInd++] + cltg[nodeInd++]; + // } else { + // nodeFreq = nodeFreq2; + // nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // } + // wgt1 = wgt2; wgt2 = getWgt(j, ref wgtMin); + // } + // //if (nodeFreq2 == 0xFFFF) { + // // nodeFreq2 = cltg[nodeInd++] + cltg[nodeInd++]; + // //} + // } //end for clen + // //if (nodeFreq2 != 0xFFFF) { nodeFreq = nodeFreq2; } + // } + //int first = 0, last = 0, prev = 0, next = 0, i = 0; + //int len = 1; + //while (i != last) { //Note: When a number points to itself, it is the largest? + // int curfreq = freq[charScan * 0x100 + clst[charScan * 0x100 + i]]; + // if (curfreq < freq[charScan * 0x100 + clst[charScan * 0x100 + prev]]) { + + // } else if (curfreq < freq[charScan * 0x100 + clst[charScan * 0x100 + next]]) { + + // } + //} + //} + + //Node table with weight/freq values and pointer info.... + + //Make Char tables to be put in ROM. + + //Compress text. + //} + //private int getWgt(int initChar, ref int wgtMin) { + // int theWgt = 0xFFFF, wfInd = 0; + // for (int i = 0; i < clen[initChar]; i++) { + // int aWgt = freq[initChar * 0x100 + clst[initChar * 0x100 + i]]; + // if (wgtMin <= aWgt) { + // if (aWgt < theWgt) { + // theWgt = aWgt; + // wfInd = initChar * 0x100 + clst[initChar * 0x100 + i]; + // } + // } + // } + // wgtMin = theWgt; + // freq[wfInd] = 0; //Temp? + // return theWgt; + //} + //Temp - For testing/ Char-pair analysis. + //public string decompStr(byte[] src, int srcInd, int num) { // int srcPos) { + // //byte[] des = new byte[0xA0000]; int desPos = 0; + // StringBuilder des = new StringBuilder(0x200); + // //short[] info = new short[0x10000]; + // //for (int srcInd1 = 0; srcInd1 <= 0x30AC; srcInd1++) { + // //int srcInd = srcInd1; + // int textTree = Bits.getInt32(src, 0xA9F54 + ((srcInd >> 8) << 3)) - 0x08000000; + // int textLenAddr = Bits.getInt32(src, 0xA9F54 + ((srcInd >> 8) << 3) + 4) - 0x08000000; + // srcInd &= 0xFF; + // while (srcInd-- != 0) { + // int cLen; + // do { + // cLen = src[textLenAddr++]; + // textTree += cLen; + // } while (cLen == 0xFF); + // } + // int initChar = 0; + // int chardata = Bits.getInt32(src, 0x60C30) - 0x08000000; + // int charpntrs = Bits.getInt32(src, 0x60C34) - 0x08000000; + // textTree <<= 3; + // do { + // int charTree = (chardata + Bits.getInt16(src, charpntrs + (initChar << 1))) << 3; + // int charSlot = charTree - 12; + // while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + // if (((src[textTree >> 3] >> (textTree++ & 7)) & 1) == 1) { + // int depth = 0; + // while (depth >= 0) { + // while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + // depth++; + // } + // charSlot -= 12; + // depth--; + // } + // } + // } + // //int loc = initChar * 0x100; + // initChar = (Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF; + // //info[loc + initChar] += 1; + // //des[desPos++] = (byte)initChar; + // if ((num == 1) && initChar < 30) { + // //des.Append("[" + initChar.ToString() + "]"); + // } else { + // des.Append((char)initChar); + // } + // } while (initChar != 0); + // //} + // //byte[] result = new byte[info.Length * sizeof(short)]; + // //Buffer.BlockCopy(info, 0, result, 0, result.Length); + // return des.ToString(); + //} + + + //Function for viewing hex-code of chars. + //void idc(byte[] src) { + // int initChar = 0; + // int chardata = Bits.getInt32(src, 0x60C30) - 0x08000000; + // int charpntrs = Bits.getInt32(src, 0x60C34) - 0x08000000; + // //textTree <<= 3; + // do { + // int charTree = (chardata + Bits.getInt16(src, charpntrs + (initChar << 1))) << 3; + // int charSlot = charTree - 12; + // int hexCode = 0; + // int flip = 1; + // while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + // flip <<= 1; //hexCode ^= flip; + // //if (((src[textTree >> 3] >> (textTree++ & 7)) & 1) == 1) { + // int depth = 0; + // while (depth >= 0) { + // while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { + // depth++; + // } + // charSlot -= 12; + // depth--; + // } + // //} + // } + // //Write char's line. + // initChar += 1; // (Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF; + // //des[desPos++] = (byte)initChar; + // //do { + // // n=getNextCharacter(argument0) + // // if n!=0 { + // // if (n<32 || n>ord('~')) { + // // if argument2 + // // { str+='['+string(n)+']'; } + // // if argument3 && (n==1 || n==3) && (p<17 || p>20) && p!=26 && p!=29 + // // { n=0 } + // // } else { str+=chr(n); } + // // } + // // p=n + // //} until n=0 + // } while (initChar < 0x100); + //} + } +} diff --git a/!Static/SpaceManager.cs b/!Static/SpaceManager.cs new file mode 100644 index 0000000..785822c --- /dev/null +++ b/!Static/SpaceManager.cs @@ -0,0 +1,292 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace gsmagic +{ + class SpaceManager + { + int list_num; + int[] freeAddr = new int[0x4000]; + int[] freeSize = new int[0x4000]; + //int organizeList(int* list) + //{ + // int i, ii, pos, val, size; + // for (i = 0; i < list_num - 1; i++) + // { + // val = list[(i << 1) + 1]; pos = i; + // for (ii = i + 1; ii < list_num; ii++) + // { + // if (list[(ii << 1) + 1] < val) + // { + // pos = ii; val = list[(ii << 1) + 1]; + // } + // } + // if (pos != i) + // { + // val = list[pos << 1]; + // size = list[(pos << 1) + 1]; + // list[pos << 1] = list[i << 1]; + // list[(pos << 1) + 1] = list[(i << 1) + 1]; + // if (val == list[i << 1]) + // { list[i << 1] = val | 0x40000000; } + // else + // { list[i << 1] = val; } + // list[(i << 1) + 1] = size; + // } + // if (list[i << 1] == list[(i - 1) << 1]) + // { + // list_num--; + // for (ii = i; ii < list_num; ii++) + // { + // list[ii << 1] = list[(ii + 1) << 1]; + // list[(ii << 1) + 1] = list[((ii + 1) << 1) + 1]; + // } + // list[list_num << 1] = 0; list[(list_num << 1) + 1] = 0; + // i--; + // } + // } + // //return list_num; + // if ((LOAD_INT(FileTable()) >> 24) != 8) + // { return list_num; } + // if ((LOAD_INT(FileTable()) & 0x1FFFFFF) != 0) + // { + // int tlist[32768]; int tnum, tnum2; tnum = list_num; + // pos = LOAD_INT(FileTable()); + // WRITE_INT(FileTable(), pos | 0x70000000); + // tnum2 = spacemanager::mapSpace(tlist); list_num = tnum; + // spacemanager::freeSpace(list, pos, (tnum2 << 3) + 4); + // } + // else + // { WRITE_INT(FileTable(), 0x7FFFFFFF); } + // pos = spacemanager::findSpace(list, (list_num << 3) + 4); + // if (pos > 0) + // { + // spacemanager::claimSpace(list, pos, (list_num << 3) + 4); + // i = 0; + // for (i = 0; i < list_num; i++) + // { + // val = list[i << 1]; + // WRITE_INT(pos + (i << 3), list[i << 1]); + // WRITE_INT(pos + (i << 3) + 4, list[(i << 1) + 1]); + // } + // WRITE_INT(pos + (list_num << 3), 0x7FFFFFFF); + // WRITE_INT((FileTable()), pos); + // //WRITE_INT(0,0x12345678); + // } + // else + // { + // WRITE_INT(FileTable(), 0x08000000); + // } + // return list_num; + //} + + int mapSpace(int* list) + { + int pos, val, size; + for (list_num = 0; list_num < 32768; list_num++) + { list[list_num] = 0; } + list_num = 0; + pos = LOAD_INT(FileTable()) & 0x09FFFFFF; + if ((pos & 0x1FFFFFF) != 0x0) + { + val = LOAD_INT(pos + (list_num << 3)); + while (val != 0x7FFFFFFF) + { + list[list_num << 1] = val; + list[(list_num << 1) + 1] = LOAD_INT(pos + 4 + (list_num << 3)); list_num++; + val = LOAD_INT(pos + (list_num << 3)); + if (val == 0) + { val = 0x7FFFFFFF; } + } + list[list_num << 1] = 0; + list[(list_num << 1) + 1] = 0; + return list_num; + } + val = 0; + do + { + if (val == 1) + { val++; continue; } + pos = LOAD_INT(FileTable() + 0x4 + (val << 2)) & 0x1FFFFFF; + if (pos > (FileTable() & 0x1FFFFFF)) + { + pos = FileSize(); + } + size = 0; + do + { size++; } + while (LOAD_BYTE(pos - size) == 0); + size--; + size = size & 0xFFFFFFFC; + pos -= size; + if (pos + size == FileSize()) + { + size += (32 << 20) - FileSize(); + } + if (size > 0) + { + list[list_num << 1] = pos | 0x08000000; + list[(list_num << 1) + 1] = size; + list_num++; + } + val++; + } + while (pos <= (FileTable() & 0x1FFFFFF)); + spacemanager::organizeList(list); + return list_num; + } + int freeSpace(int* list, int pos, int size) + { + int i, ii, index, pos2, pos3; index = -1; pos2 = pos + size; + pos |= 0x10000000; + for (i = 0; i < list_num; i++) + { + if ((list[i << 1] & 0x1FFFFFF) > (pos & 0x1FFFFFF)) + { + if ((pos2 & 0x1FFFFFF) >= (list[i << 1] & 0x1FFFFFF)) + { + pos = pos & 0x09FFFFFF | (list[i << 1] & 0xF6000000); + pos3 = list[i << 1] + list[(i << 1) + 1]; + if ((pos3 & 0x1FFFFFF) > (pos2 & 0x1FFFFFF)) + { + pos2 = pos3; + size = (pos2 & 0x09FFFFFF) - (pos & 0x09FFFFFF); + } + list_num -= 1; + for (ii = i; ii < list_num; ii++) + { + list[ii << 1] = list[(ii + 1) << 1]; + list[(ii << 1) + 1] = list[((ii + 1) << 1) + 1]; + } + list[list_num << 1] = 0; + list[(list_num << 1) + 1] = 0; + i = -1; + } + } + else + { + pos3 = list[i << 1] + list[(i << 1) + 1]; + if ((pos & 0x1FFFFFF) <= (pos3 & 0x1FFFFFF)) + { + pos = list[i << 1]; + if ((pos3 & 0x1FFFFFF) > (pos2 & 0x1FFFFFF)) + { + pos2 = pos3; + } + size = (pos2 & 0x09FFFFFF) - (pos & 0x09FFFFFF); + list_num -= 1; + for (ii = i; ii < list_num; ii++) + { + list[ii << 1] = list[(ii + 1) << 1]; + list[(ii << 1) + 1] = list[((ii + 1) << 1) + 1]; + } + list[list_num << 1] = 0; + list[(list_num << 1) + 1] = 0; + i = -1; + } + } + } + + list[list_num << 1] = (pos & 0x1FFFFFF) | 0x08000000; + if ((pos >> 28) == 1) + { list[list_num << 1] |= 0x10000000; } + else + { + for (i = 0; i < size; i++) + { WRITE_BYTE(pos + i, 0); } + } + list[(list_num << 1) + 1] = size; + list_num++; + spacemanager::organizeList(list); + return list_num; + } + //int findSpace(int size, int alignment) + //{ + + // return 0; + //} + int claimSpace(int size, int alignment) + { + //size=(size+3)&0xFFFFFFFC; + if (size <= 0) + { return -list_num; } + + //Find space + int pos = -1, i; + for (i = 0; i < list_num; i++) + { + + //if ((pos >= 0) //Following operations require this variable, and so to skip them, we have this. + // && (((freeAddr[pos] & alignment) == 0) && ((freeAddr[i] & alignment) != 0)) //Only assign aligned addresses when possible. + // )//|| (freeSize[i] <= freeSize[pos])) //Find smallest size acceptable. + //{ + // continue; + //} + //If/else so I can THINK for once! + if (pos >= 0) //Following operations require this variable, and so to skip them, we have this. + { + if ((freeAddr[i] & alignment) == 0) + { + if ((freeAddr[pos] & alignment) != 0) //Only assign aligned addresses when possible. + { + if (size <= freeSize[i]) //Makes sure we have enough space here. + { + pos = i; + } + } + } + else + { + if (freeSize[i] <= freeSize[pos]) //Find smallest size acceptable. + { + if (size <= freeSize[i]) //Makes sure we have enough space here. + { + pos = i; + } + } + } + } + else + { + if (size <= freeSize[i]) //Makes sure we have enough space here. + { + pos = i; + } + } + } + + + i = pos; + if (pos == -1) //No space found. (Todo: Calculate total free space, and make some room?) + { return pos; } + pos = freeAddr[pos];//Todo: Check alignment + + //if (spacemanager::confirmSpace(list, pos, size) <= 0) + //{ return -list_num; } + + freeAddr[i] += size; + freeSize[i] -= size; + + if (freeSize[i] == 0) //Remove entry + { + list_num -= 1; + freeAddr[i] = freeAddr[list_num]; + freeSize[i] = freeSize[list_num]; + //for (i = index; i < list_num; i++) + //{ + // list[i << 1] = list[(i + 1) << 1]; + // list[(i << 1) + 1] = list[((i + 1) << 1) + 1]; + //} + //list[list_num << 1] = 0; list[(list_num << 1) + 1] = 0; + } + + //spacemanager::organizeList(list); + //return list_num; + return pos; + } + + } +} diff --git a/!Static/globals.cs b/!Static/globals.cs new file mode 100644 index 0000000..527eb62 --- /dev/null +++ b/!Static/globals.cs @@ -0,0 +1,17 @@ +//using System.Windows.Forms; //Control +using System.Drawing; //Point, Size +namespace gsmagic +{ + static class Globals //Mainly Global Variables. (Probably will be ROM'specific addresses loaded from an xml or json file/not sure.) + { + //Try not to put too much here, as Globals/statics are not that flexible? (Consider storing datatypes in a class/object, and linking from here, if needed?) + + //Wasn't sure about putting this here - Further planning needed? - Either way, the program does need cleanup, so... + static public Form1 mainForm; + static public Editors editorsForm; + + //Not sure if doing new Font objects are slow... But either way, this is reused for most Controls, so here is a central place to edit it. + //static public Font font = new Font("Lucida Console", 8, FontStyle.Regular, GraphicsUnit.Point, 0); + static public Font font = new Font("Consolas", 8, FontStyle.Regular, GraphicsUnit.Point, 0); // Shorter width, but taller? + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74ea502 --- /dev/null +++ b/.gitignore @@ -0,0 +1,528 @@ + +# Created by https://www.gitignore.io/api/csharp,windows,visualstudio +# Edit at https://www.gitignore.io/?templates=csharp,windows,visualstudio + +### Csharp ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ +# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true +**/wwwroot/lib/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### VisualStudio ### + +# User-specific files + +# User-specific files (MonoDevelop/Xamarin Studio) + +# Build results + +# Visual Studio 2015/2017 cache/options directory +# Uncomment if you have tasks that create the project's static files in wwwroot + +# Visual Studio 2017 auto generated files + +# MSTest test Results + +# NUNIT + +# Build Results of an ATL Project + +# Benchmark Results + +# .NET Core + +# StyleCop + +# Files built by Visual Studio + +# Chutzpah Test files + +# Visual C++ cache files + +# Visual Studio profiler + +# Visual Studio Trace Files + +# TFS 2012 Local Workspace + +# Guidance Automation Toolkit + +# ReSharper is a .NET coding add-in + +# JustCode is a .NET coding add-in + +# TeamCity is a build add-in + +# DotCover is a Code Coverage Tool + +# AxoCover is a Code Coverage Tool + +# Visual Studio code coverage results + +# NCrunch + +# MightyMoose + +# Web workbench (sass) + +# Installshield output folder + +# DocProject is a documentation generator add-in + +# Click-Once directory + +# Publish Web Output +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted + +# NuGet Packages +# The packages folder can be ignored because of Package Restore +# except build/, which is used as an MSBuild target. +# Uncomment if necessary however generally it will be regenerated when needed +# NuGet v3's project.json files produces more ignorable files + +# Microsoft Azure Build Output + +# Microsoft Azure Emulator + +# Windows Store app package directories and files + +# Visual Studio cache files +# files ending in .cache can be ignored +# but keep track of directories ending in .cache + +# Others + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true + +# RIA/Silverlight projects + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) + +# SQL Server files + +# Business Intelligence projects + +# Microsoft Fakes + +# GhostDoc plugin setting file + +# Node.js Tools for Visual Studio + +# Visual Studio 6 build log + +# Visual Studio 6 workspace options file + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) + +# Visual Studio LightSwitch build output + +# Paket dependency manager + +# FAKE - F# Make + +# JetBrains Rider + +# CodeRush personal settings + +# Python Tools for Visual Studio (PTVS) + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio + +# Telerik's JustMock configuration file + +# BizTalk build output + +# OpenCover UI analysis results + +# Azure Stream Analytics local run output + +# MSBuild Binary and Structured Log + +# NVidia Nsight GPU debugger configuration file + +# MFractors (Xamarin productivity tool) working folder + +# Local History for Visual Studio + +# BeatPulse healthcheck temp database + +# End of https://www.gitignore.io/api/csharp,windows,visualstudio diff --git a/App.config b/App.config new file mode 100644 index 0000000..ce740f2 --- /dev/null +++ b/App.config @@ -0,0 +1,21 @@ + + + + +
+ + + + + + + + + + + + 0 + + + + \ No newline at end of file diff --git a/Controls/ButtonL.cs b/Controls/ButtonL.cs new file mode 100644 index 0000000..431cdcd --- /dev/null +++ b/Controls/ButtonL.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //Control +using System.Drawing; //Point, Size +namespace gsmagic +{ + class ButtonL : Button + { + Control pnl; + public byte[] buf; + public int addr; + public int bits; + //public List itemsL; + public byte[] txt; + + public List items; + + //String[] items; + //int index = 0; + //protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + //{ + // if (keyData == Keys.Down || keyData == Keys.Up) + // { + // // Process keys + // Text = "TEST"; + // return true; + // } + // return false; + //} + //override = Since we are inheritting from Button, these are the functions we are replacing? + protected override bool IsInputKey(Keys keyData) + { + switch (keyData) + { + case Keys.Up: + case Keys.Down: + return true; + } + return base.IsInputKey(keyData); + } + //protected override void OnKeyDown(KeyEventArgs e) + //{ + // base.OnKeyDown(e); + // switch (e.KeyCode) + // { + // case Keys.Up: + // break; + // case Keys.Down: + // break; + // } + //} + public Control doCombo(Control panel, int x, int y, byte[] textBank, List items, byte[] buffer, int address, int numOfBits) + { + pnl = panel; + AutoEllipsis = true; //If false: If text string too long and lacking spaces, text can disappear. + Location = new Point(x, y); + //bn.Width = 180; + Size = new Size(180, 20); + Font = Globals.font; //new Font("Lucida Console", 8, FontStyle.Regular, GraphicsUnit.Point, 0); + //bn.DropDownStyle = ComboBoxStyle.DropDownList; + //bn.Items.AddRange(items); + pnl.Controls.Add(this); + //ctrls.Add(this); + //itemsL = items.ToList(); + buf = buffer; + addr = address; //offsets.Add(offset); + bits = numOfBits; //bits.Add(numOfBits); + TextAlign = ContentAlignment.MiddleLeft; + //bn.SelectedIndexChanged += new EventHandler(comboChanged); + //cmb.DrawMode = DrawMode.OwnerDrawFixed; + //return cmb; + + txt = textBank; + this.items = items; + + PreviewKeyDown += new PreviewKeyDownEventHandler(comboKeyDown); + //bn.MouseClick += new MouseEventHandler(nudrc); + Click += test; + return this; + } + //private void test(object sender, EventArgs e) { + // curList = (ButtonL)sender; + // int i = ctrls.IndexOf((Button)sender); + // //sl2.mItems = itemsL[i]; + // //sl2.Tb_TextChanged(null, null); + // lpnl.Show(); + // initHiddenList() + //} + ButtonL curList; + Panel lpnl = new Panel(); + public SearchList sl2 = new SearchList(); + + //private int tt() { + // return 0; + //} + //Action aa;// = tt; + //Object aaa = tt; + //Func aab;//b; = tt;//object tta = tt; + private void test(object sender, EventArgs e) //(object sender, EventArgs e) + { + //Small code hack to support the sorting w/o opening pop-up list... + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + { + //aa = tt;//nudrc(sender, null); + //aab = tt; + return; + } + //lpnl.Hide(); + //pnl.BackColor = Color.Brown; + lpnl = new Panel(); + curList = (ButtonL)sender; + //sl2.mItems = itemsL[i]; + //sl2.Tb_TextChanged(null, null); + lpnl.Show(); + + sl2.doTableListbox(lpnl, txt, items); + lpnl.Left = 300; + lpnl.Width = 250; + lpnl.Top = 20; + lpnl.Height = pnl.Height - 40; + sl2.lv.Height -= 20; + + Button ok = new Button(); + ok.Left = 0; + ok.Top = lpnl.Height - 20; + //cntAddr.Text = lpnl.Height.ToString(); + ok.Width = 120; + ok.Height = 20; + ok.Text = "Ok"; + lpnl.Controls.Add(ok); + ok.Click += okClick; + + Button cancel = new Button(); + cancel.Left = 120; + cancel.Top = lpnl.Height - 20; + cancel.Width = 120; + cancel.Height = 20; + cancel.Text = "Cancel"; + lpnl.Controls.Add(cancel); + cancel.Click += cancelClick; + + //pnl.Controls.Add(sl2); + pnl.Controls.Add(lpnl); + lpnl.BringToFront(); + //ok.BringToFront(); + } + private void okClick(object sender, EventArgs e) + { + lpnl.Hide(); + curList.Focus(); + //int i = ctrls.IndexOf((ButtonL)curList); + //int value = (int)((ListView)sl2.lv)..SelectedIndex; + if (sl2.lv.SelectedIndices.Count != 1) { return; } + int value = sl2.sItems[sl2.lv.SelectedIndices[0]]; + for (int j = 0; j < bits; j += 8) + { + buf[addr + (j >> 3)] = (byte)value; + value >>= 8; + } + value = Bits.getBits(buf, addr, bits); + Text = Bits.getTextShort(txt, items[value]);//itemsL[value].ToString(); + } + private void cancelClick(object sender, EventArgs e) + { + lpnl.Hide(); + curList.Focus(); + } + //private void comboChanged(object sender, EventArgs e) + //{ + // int i = ctrls.IndexOf((ComboBox)sender); + // int value = (int)((ComboBox)sender).SelectedIndex; + // for (int j = 0; j < bits[i]; j += 8) + // { + // buf[entryAddr + offsets[i] + (j >> 3)] = (byte)value; + // value >>= 8; + // } + //} + + private void comboKeyDown(object sender, PreviewKeyDownEventArgs e) + { + //base.comboKeyDown(e); + //base.OnKeyDown(e); + //e..Handled = true; + int value = Bits.getBits(buf, addr, bits); + switch (e.KeyCode) + { + //case Keys.Left: + //case Keys.Right: + case Keys.Up: + if (value <= 0) { break; } + Bits.setBits(buf, addr, bits, --value); + Text = Bits.getTextShort(txt, sl2.mItems[sl2.sItems[value]]); //itemsL[value].ToString(); + break; + case Keys.Down: + if (value >= items.Count() - 1) { break; } + Bits.setBits(buf, addr, bits, ++value); + Text = Bits.getTextShort(txt, sl2.mItems[sl2.sItems[value]]); //itemsL[value].ToString(); + break; + } + //int value = (int)((ComboBox)sender).SelectedIndex; + //for (int j = 0; j < bits[i]; j += 8) + //{ + // buf[entryAddr + offsets[i] + (j >> 3)] = (byte)value; + // value >>= 8; + //} + } + } +} \ No newline at end of file diff --git a/Controls/DataNud.cs b/Controls/DataNud.cs new file mode 100644 index 0000000..27d0f29 --- /dev/null +++ b/Controls/DataNud.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //Control +using System.Drawing; //Point, Size +namespace gsmagic +{ + class DataNud : NumericUpDown + { + //public NumericUpDown nud; + public byte[] buf; + public int addr; + public int bits; + public NumericUpDown doNud(Control pnl, int x, int y, byte[] buffer, int address, int numOfBits) + { + //nud = new NumericUpDown(); + //nud1.Location = new Point(pnl.Width / 2 - 50, pnl.Height / 2 - 100); + Location = new Point(x, y); + Width = 100;//nud1.Size = new Size(200, 100); + Font = Globals.font; //new Font("Lucida Console", 8, FontStyle.Regular, GraphicsUnit.Point, 0); + pnl.Controls.Add(this); + buf = buffer; + addr = address; //offsets.Add(offset); + bits = numOfBits; //bits.Add(numOfBits); + ValueChanged += new EventHandler(nudChanged); + //nud.MouseClick += new MouseEventHandler(nudrc); + Maximum = ((long)1 << numOfBits) - 1; //if not long, 32+ will be 0.... so -1 + return this; + } + private void nudChanged(object sender, EventArgs e) + { + //int i = ctrls.IndexOf((NumericUpDown)sender); + int value = (int)((NumericUpDown)sender).Value; + for (int j = 0; j < bits; j += 8) + { + buf[addr + (j >> 3)] = (byte)value; + value >>= 8; + } + } + //public void getData() + //{ + // Value = Bits.getBits(buf, addr, bits); + //} + } +} diff --git a/Controls/DataTextbox.cs b/Controls/DataTextbox.cs new file mode 100644 index 0000000..9640807 --- /dev/null +++ b/Controls/DataTextbox.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //Control +using System.Drawing; //Point, Size + +namespace gsmagic +{ + class DataTextbox + { + Control pnl; + public byte[] txt; + public int baseIndex; + public int theIndex; + public TextBox tbx = new TextBox(); + public Button bn = new Button(); + public void doTextbox(Control panel, int x, int y, byte[] textBuf, int index) + { + pnl = panel; + + tbx.Location = new Point(x, y); + tbx.Width = 120; + tbx.Font = Globals.font; + pnl.Controls.Add(tbx); + //ctrls.Add(tbx); + + txt = textBuf; + baseIndex = index; + theIndex = index; + + //Attach Edit button! + bn.Location = new Point(x + tbx.Width, y); + bn.Width = 50; + bn.Height = 20; + bn.Font = Globals.font; + bn.Text = "Edit"; + bn.Click += button_Click; + pnl.Controls.Add(bn); + } + + private void button_Click(object sender, EventArgs e) + { //TODO Move decomptext to Form1, compress text on save. + // * Function may need refactoring, but it works. + String str = tbx.Text; //textBox1.Text; + byte[] bytes = new byte[0x200]; + int a = 0, b = 0; + while (a < str.Length) + { + if (str[a] == '[') + { + int num = 0; + while (str[++a] != ']') + { + num = (num * 10) + (byte)(str[a]) - 0x30; + } + a++; + bytes[b++] = (byte)num; + } + else if (((byte)str[a] == 13) && ((byte)str[a + 1] == 10)) + { + a += 2; + } + else + { + bytes[b++] = (byte)str[a++]; + } + } + b++; //B/c 00 character at end. + //byte[] bytes = toRawStrData(textBox1.Text); + //int b = bytes.Length + 1; //=0x200 + 1 (NEEDS FIXING) + //if (listView1.SelectedIndices.Count != 1) { return; } + int srcEntry = theIndex * 4; + //int srcEntry = listBox2.SelectedIndex * 4; + int neaddr = 0xC300 + Bits.getInt32(txt, srcEntry + 4); + int lendif = Bits.getInt32(txt, srcEntry) - Bits.getInt32(txt, srcEntry + 4) + b; + int c = srcEntry + 4; + while ((Bits.getInt32(txt, c) != 0)) + { + Bits.setInt32(txt, c, Bits.getInt32(txt, c) + lendif); + c += 4; + } + c = 0xC300 + Bits.getInt32(txt, c - 4) - lendif; + while (txt[c++] != 0) { } + if (Bits.getInt32(txt, srcEntry + 4) != 0) { Array.Copy(txt, neaddr, txt, 0xC300 + Bits.getInt32(txt, srcEntry + 4), c - neaddr); } + int d = 0xC300 + Bits.getInt32(txt, srcEntry); + while (b-- > 0) + { + txt[d] = bytes[d++ - (0xC300 + Bits.getInt32(txt, srcEntry))]; + } + Comp.comptext(txt, Globals.mainForm.rom); + //b=length needed. ; small - big + length + //listView1.Invalidate(); + } + } +} diff --git a/Controls/SearchList.cs b/Controls/SearchList.cs new file mode 100644 index 0000000..dcd42df --- /dev/null +++ b/Controls/SearchList.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //Control +using System.Drawing; //Point, Size +namespace gsmagic +{ + class SearchList + { + Control pnl; + public List mItems; + public List sItems; + + public TextBox tb; + public ListView lv; + + byte[] txt; + //int index; + //int size; + public void doTableListbox(Control panel, byte[] textBank, List items) + { + pnl = panel; + + tb = new TextBox(); + //tb.Location = new Point(0, 0); + tb.Width = 240; //lv.Size = new Size(250, pnl.Height); + tb.Font = Globals.font; + pnl.Controls.Add(tb); + tb.TextChanged += Tb_TextChanged; + + txt = textBank; + //this.index = index; + //this.size = size; + //sItems = mItems; + mItems = items; + + lv = new ListView(); + lv.BackColor = Color.FromArgb(0x08, 0x70, 0x98); lv.ForeColor = Color.White; + lv.HideSelection = false; + lv.MultiSelect = false; + + ColumnHeader header = new ColumnHeader(); + header.Text = ""; + header.Name = "col1"; + //header.Width = 240 + 240 + 240; + //header.Width = pnl.Width; //lv.Width - 4 - SystemInformation.VerticalScrollBarWidth; //Check if scrollba/turn it "always on"? + lv.Columns.Add(header); + //lv.Columns[lv.Columns.Count - 1].Width = -2; + //listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); + + //listView1.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + var doubleBufferPropertyInfo = lv.GetType().GetProperty("DoubleBuffered", + System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + doubleBufferPropertyInfo.SetValue(lv, true, null); + + lv.Location = new Point(0, 20); + lv.Size = new Size(240, pnl.Height - 20); + pnl.Controls.Add(lv); + + lv.Columns[0].Width = 0x7FFF;//lv.Width - 4 - SystemInformation.VerticalScrollBarWidth; //0x7FFF = largest possible. + + // + lv.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; //| AnchorStyles.Right); + lv.FullRowSelect = true; + lv.HeaderStyle = ColumnHeaderStyle.None; + lv.Font = Globals.font; + //lv.Alignment=ListViewAlignment. + lv.View = View.Details; + //lv.VirtualListSize = 0; + lv.VirtualMode = true; + lv.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(lv_RetrieveVirtualItem); + //lv.SelectedIndexChanged += new EventHandler(loadEntry); + + //cntAddr = doLabel(250, 0, ""); + + //lv.VirtualListSize = mItems.Count; + Tb_TextChanged(null, null); + //lv.Items[0].Focused = true; + //lv.Items[0].Selected = true; + } + + public void Tb_TextChanged(object sender, EventArgs e) + { + //if (mItems == null) + // return; + //sItems = new List(); + //for (int i = 0; i < mItems.Count; i++) + //{ + // //foreach (string a in mItems) { + // if (mItems[i].Contains(tb.Text)) + // { + // sItems.Add(i); + // } + // //if tb.Text in a { } + //} + //lv.VirtualListSize = sItems.Count; + //throw new NotImplementedException(); + sItems = Bits.getTextMatches(txt, tb.Text, mItems); + lv.VirtualListSize = sItems.Count; + } + + private void lv_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + if (sItems == null) + { + e.Item = new ListViewItem("null"); + return; + } + if (sItems[e.ItemIndex] == -1) + { + e.Item = new ListViewItem("null2"); + return; + } + //e.Item = new ListViewItem(mItems[sItems[e.ItemIndex]]); + e.Item = new ListViewItem((sItems[e.ItemIndex]).ToString().PadLeft(5, ' ') + "|" + Bits.getTextShort(txt, mItems[sItems[e.ItemIndex]])); + } + + + //Dark Dawn compatibility + public void doTableListbox2(Control panel, byte[] textBank, List items) + { + pnl = panel; + + tb = new TextBox(); + tb.Width = 240; + tb.Font = Globals.font; + pnl.Controls.Add(tb); + tb.TextChanged += Tb_TextChanged2; + + txt = textBank; + mItems = items; + + lv = new ListView(); + lv.BackColor = Color.FromArgb(0x08, 0x70, 0x98); lv.ForeColor = Color.White; + lv.HideSelection = false; + lv.MultiSelect = false; + + ColumnHeader header = new ColumnHeader(); + header.Text = ""; + header.Name = "col1"; + lv.Columns.Add(header); + var doubleBufferPropertyInfo = lv.GetType().GetProperty("DoubleBuffered", + System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + doubleBufferPropertyInfo.SetValue(lv, true, null); + + lv.Location = new Point(0, 20); + lv.Size = new Size(240, pnl.Height - 20); + pnl.Controls.Add(lv); + + lv.Columns[0].Width = 0x7FFF;//lv.Width - 4 - SystemInformation.VerticalScrollBarWidth; //0x7FFF = largest possible. + + lv.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; //| AnchorStyles.Right); + lv.FullRowSelect = true; + lv.HeaderStyle = ColumnHeaderStyle.None; + lv.Font = Globals.font; + lv.View = View.Details; + lv.VirtualMode = true; + lv.RetrieveVirtualItem += new RetrieveVirtualItemEventHandler(lv_RetrieveVirtualItem2); + Tb_TextChanged2(null, null); + } + + public void Tb_TextChanged2(object sender, EventArgs e) + { + sItems = Bits.getTextMatches2(txt, tb.Text, mItems); + lv.VirtualListSize = sItems.Count; + } + + private void lv_RetrieveVirtualItem2(object sender, RetrieveVirtualItemEventArgs e) + { + if (sItems == null) + { + e.Item = new ListViewItem("null"); + return; + } + if (sItems[e.ItemIndex] == -1) + { + e.Item = new ListViewItem("null2"); + return; + } + //e.Item = new ListViewItem(mItems[sItems[e.ItemIndex]]); + e.Item = new ListViewItem((sItems[e.ItemIndex]).ToString().PadLeft(5, ' ') + "|" + Bits.getText2(txt, mItems[sItems[e.ItemIndex]])); + } + } +} diff --git a/Dark Dawn - Copy.cs b/Dark Dawn - Copy.cs new file mode 100644 index 0000000..c34fc9f --- /dev/null +++ b/Dark Dawn - Copy.cs @@ -0,0 +1,300 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //MessageBox + +namespace gsmagic +{ + class Dark_Dawn + { + public void extract() + { + byte[] buffer = System.IO.File.ReadAllBytes(@"C:\Users\Tea\Desktop\yamata.dmp");// gs3battleram.dmp"); + //int entry = 0; + int address = 0x23C310;//int address = 0x17726C; + System.Text.StringBuilder strbuild = new System.Text.StringBuilder(0x1000); + + //int entries = 130; + while (true) + { + int a = Bits.getInt32(buffer, address); + if (a == -1) break; + getText(strbuild, buffer, address); + strbuild.AppendLine(); + address += 4; + } + System.IO.File.WriteAllText(@"C:\Users\Tea\Desktop\text.txt", strbuild.ToString()); + //while (address < 0x17BE64) { + + + // byte[] buffer = System.IO.File.ReadAllBytes(@"C:\Users\Tea\Desktop\gs3battleram.dmp"); + // int entry = 0; + // int address = 0x668b8;//int address = 0x17726C; + // System.Text.StringBuilder strbuild = new System.Text.StringBuilder(160); + + // int entries = 130; + // while (entries-- > 0) { + //while (address < 0x17BE64) { + //int nameID = Bits.getInt16(buffer, address); + + //if (entry + 0xB != nameID) + //MessageBox.Show(entry + "---" + nameID); + //int addr2 = Bits.getInt32(buffer, 0x23C328 + ((0x16E + entry) << 2)); + //int length = 20; int pos = addr2 & 0xFFFFFF; + ////MessageBox.Show(addr2.ToString("x8")); + //while (length-- > 0) + //{ + // int c = Bits.getInt16(buffer, pos); pos += 2; + // if (c == 0) + // break; + // if (c < 0x100) + // strbuild.Append((char)c); + // //else + // // strbuild.Append("["+(char)c+"]"); + //} + + //return strbuild.ToString(); + //MessageBox.Show(strbuild.ToString()); + //There's a hard-limit of <20 for Enemy Names, anyway. + //strbuild.AppendLine(); + + //getText(strbuild, buffer, 0x23C328 + ((0x16E + entry) << 2)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt32(buffer, address)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 4]); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 5]); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt16(buffer, address + 6)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt16(buffer, address + 8)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt16(buffer, address + 10)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt16(buffer, address + 12)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + Bits.getInt16(buffer, address + 14)); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 16]); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 17]); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 18]); + //strbuild.Append((char)0x09); + //strbuild.Append("" + buffer[address + 19]); + + //int itemid = Bits.getInt16(buffer, address + 0x14); + //getText(strbuild, buffer, 0x220E54 + ((0 + itemid) << 2)); + //int itemamt = buffer[address + 0x1C]; + //if (itemamt != 0) + // strbuild.Append(" x" + itemamt); + //strbuild.Append((char)0x09); + //itemid = Bits.getInt16(buffer, address + 0x16); + //getText(strbuild, buffer, 0x220E54 + ((0 + itemid) << 2)); + //itemamt = buffer[address + 0x1D]; + //if (itemamt != 0) + // strbuild.Append(" x" + itemamt); + //strbuild.Append((char)0x09); + //itemid = Bits.getInt16(buffer, address + 0x18); + //getText(strbuild, buffer, 0x220E54 + ((0 + itemid) << 2)); + //itemamt = buffer[address + 0x1E]; + //if (itemamt != 0) + // strbuild.Append(" x" + itemamt); + //strbuild.Append((char)0x09); + //itemid = Bits.getInt16(buffer, address + 0x1A); + //getText(strbuild, buffer, 0x220E54 + ((0 + itemid) << 2)); + //itemamt = buffer[address + 0x1F]; + //if (itemamt != 0) + // strbuild.Append(" x" + itemamt); + //strbuild.Append((char)0x09); + + //int eType = buffer[address + 0x20]; + //if (eType == 0) + // strbuild.Append("Venus"); + //if (eType == 1) + // strbuild.Append("Mercury"); + //if (eType == 2) + // strbuild.Append("Mars"); + //if (eType == 3) + // strbuild.Append("Jupiter"); + //if (eType == 4) + // strbuild.Append("Neutral"); + + //strbuild.Append(buffer[address + 0x21]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x22]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x23]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x24]); + //strbuild.Append((char)0x09); + + //if (buffer[address + 0x25] != 0) + // strbuild.Append("YAY!!!"); //Making it obvious. / There were no matches. + //strbuild.Append(buffer[address + 0x25]); + + //strbuild.Append(Bits.getInt16(buffer, address + 0x26)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x28)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x2A)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x2C)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x2E)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x30)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x32)); + //strbuild.Append((char)0x09); + //strbuild.Append(Bits.getInt16(buffer, address + 0x34)); + //strbuild.Append((char)0x09); + + //strbuild.Append(buffer[address + 0x36]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x37]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x38]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x39]); //All 0s, so likely unused. + //strbuild.Append((char)0x09); + + //int f = buffer[address + 0x38]; + //for (int i = 0; i < 8; i++) + //{ + // if ((f & 1) == 1) + // strbuild.Append("*"); + // f >>= 1; + // int psyid = Bits.getInt16(buffer, address + 0x3A + i * 2); + // getText(strbuild, buffer, 0x221B5C + ((0 + psyid) << 2)); + // //strbuild.Append(); + // strbuild.Append((char)0x09); + //} + + //strbuild.Append(buffer[address + 0x4A]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x4B]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0x4C]); + + //strbuild.Append(Bits.getInt16(buffer, address + 0x4E)); + + //int itemid = Bits.getInt16(buffer, address + 0x50); + //getText(strbuild, buffer, 0x220E54 + ((0 + itemid) << 2)); + //strbuild.Append((char)0x09); + + //int ic = Bits.getInt16(buffer, address + 0x52); + //if (ic == 0) + // strbuild.Append("Never"); + //if (ic == 1) + // strbuild.Append("1/1"); + //if (ic == 2) + // strbuild.Append("1/2"); + //if (ic == 3) + // strbuild.Append("1/4"); + //if (ic == 4) + // strbuild.Append("1/8"); + //if (ic == 5) + // strbuild.Append("1/16"); + //if (ic == 6) + // strbuild.Append("1/32"); + //if (ic == 7) + // strbuild.Append("1/64"); + //if (ic == 8) + // strbuild.Append("1/128"); + //if (ic == 9) + // strbuild.Append("1/256"); + //strbuild.Append(Bits.getInt16(buffer, address + 0x52)); + + //strbuild.Append(Bits.getInt16(buffer, address + 0x54)); + //getText(strbuild, buffer, 0x222EAC + ((0 + entry) << 2)); + + //strbuild.Append(Bits.getInt32(buffer, address - 4)); //ID + //strbuild.Append(Bits.getInt32(buffer, address)); //Class Type + //strbuild.Append(buffer[address + 4]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 5]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 6]); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 7]); + //strbuild.Append((char)0x09); + + //strbuild.Append(buffer[address + 8] + "0%"); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 9] + "0%"); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0xA] + "0%"); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0xB] + "0%"); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0xC] + "0%"); + //strbuild.Append((char)0x09); + //strbuild.Append(buffer[address + 0xD] + "0%"); + //strbuild.Append((char)0x09); + + //for (int i = 0; i < 16; i++) + //{ + // int psyid = Bits.getInt16(buffer, address + 0xE + i * 4); + // getText(strbuild, buffer, 0x221B5C + ((0 + psyid) << 2)); + // strbuild.Append((char)0x09); + // strbuild.Append(Bits.getInt16(buffer, address + 0x10 + i * 4)); + // strbuild.Append((char)0x09); + //} + + strbuild.Append(buffer[address + 0x4E]); + strbuild.Append((char)0x09); + strbuild.Append(buffer[address + 0x4F]); + strbuild.Append((char)0x09); + strbuild.Append(buffer[address + 0x50]); + + strbuild.AppendLine(); //0x0D, 0x0A + + //strbuild.AppendLine("Enemy ID: " + Bits.getInt32(buffer, address)); + //strbuild.AppendLine("Level: " + buffer[address + 4]); + //strbuild.AppendLine("?: " + buffer[address + 5]); + //strbuild.AppendLine("HP: " + Bits.getInt16(buffer, address + 6)); + //strbuild.AppendLine("PP: " + Bits.getInt16(buffer, address + 8)); + //strbuild.AppendLine("Attack: " + Bits.getInt16(buffer, address + 10)); + //strbuild.AppendLine("Defense: " + Bits.getInt16(buffer, address + 12)); + //strbuild.AppendLine("Agility: " + Bits.getInt16(buffer, address + 14)); + //strbuild.AppendLine("Luck: " + buffer[address + 16]); + //strbuild.AppendLine("Turns: " + buffer[address + 17]); + //strbuild.AppendLine("HP Regen: " + buffer[address + 18]); + //strbuild.AppendLine("PP Regen: " + buffer[address + 19]); + + //strbuild.AppendLine(); //0x0D, 0x0A + + + + //Class data + + + // entry += 1; + // address += 0x58; //address += 0x58; + //} + //System.IO.File.WriteAllText(@"C:\Users\Tea\Desktop\gs3enemiestab.txt", strbuild.ToString()); + //0x17726C + entry * 0x58; + } + //0x16E + void getText(System.Text.StringBuilder strbuild, byte[] buffer, int address) + { + int addr2 = Bits.getInt32(buffer, address); + int length = 2000; int pos = addr2 & 0xFFFFFF; + //MessageBox.Show(addr2.ToString("x8")); + while (length-- > 0) + { + int c = Bits.getInt16(buffer, pos); pos += 2; + if (c == 0) + break; + if ((c < 0x100) && (c > 0xF)) + strbuild.Append((char)c); + else + strbuild.Append("["+c.ToString("X4")+"]"); + } + } +} +} diff --git a/Dark Dawn.cs b/Dark Dawn.cs new file mode 100644 index 0000000..519e1ab --- /dev/null +++ b/Dark Dawn.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //MessageBox + +using System.IO; +namespace gsmagic +{ + class Dark_Dawn + { + string path = ""; + byte[] header;// = new byte[0x200]; + byte[] fnt; //File Name Table + byte[] fat; //File Allocation Table + byte[] ovr; //Overlay entries + byte[] ram = new byte[0x400000]; + public void init(string aPath) + { + path = aPath; + header = Bits.openFilePart(path, 0, 0x200); + fnt = Bits.openFilePart(path, Bits.getInt32(header, 0x40), Bits.getInt32(header, 0x44)); + fat = Bits.openFilePart(path, Bits.getInt32(header, 0x48), Bits.getInt32(header, 0x4C)); + ovr = Bits.openFilePart(path, Bits.getInt32(header, 0x50), Bits.getInt32(header, 0x54)); + //Title check? + loadARM9(); + loadFile(0x154); + //Overlay File 0x151 / Battle Stuff + //loadFile(0x181);//0x11AD+1+0x16E);// 0x1383);//0xFC7 + 8); //0x1134);// 0xD07 + 48*8); + loadFile(0xD07); + //doTextFile(); + doTextFiles(); + Form dd = new Form(); + dd.Text = "Dark Dawn WIP - " + path; + dd.Width = 800; + dd.Height = 600; + dd.Show(); + dd.Activate();//dd.Focus(); + //dd.TopMost = true; + //dd.ShowDialog(); + + TabControl a = new TabControl(); + a.Width = dd.Width; + a.Height = dd.Height; + + a.Controls.Add(new TabPage("Enemies")); + //loadEnemies(a); + + TabPage d = new TabPage(); + d.Text = "Djinn"; + a.Controls.Add(d); + + dd.Controls.Add(a); + loadEnemies(a); + //File.WriteAllBytes(path + "ram.bin", ram); + + Button s = new Button(); + s.Left = a.Width;// - 100; + s.Top = 0; + dd.Controls.Add(s); + s.MouseClick += new MouseEventHandler(saveClick); + } + void saveClick(object sender, MouseEventArgs e) + { + loadFile(0); //TEST + saveFile(0); + } + void loadEnemies(TabControl a) + { + TabPage d = a.SelectedTab; + Table_Manager tm = new Table_Manager(); + tm.setTable(ram, 0x17726C, 0x58); + tm.setPanel(a.SelectedTab);//tabPage6); + int pnlx = 250; //d.Width / 2 - 150 + 50; + int pnly = 20; // d.Height / 2 - 125; + //d.Text = "Forge"; + List items = new List();// = {5, 6, 7 }; + items.Add(5); + String[] text = { "" };// "Processed", "Rusted" }; + + //tm.doCombo(pnlx + 200, pnly + 20, Bits.textToBytes(text) + //tm.doTableListbox2(Bits.textToBytes(text), Bits.numList(83)); + tm.doTableListbox2(ram, Bits.numList(366, 221)); + String[] lbl = { "ID", "Level", "Type", "HP", "PP", "Attack", "Defense", "Agility", "Luck", "Turns", "HP Regen", "PP Regen" }; + for (int i = 0; i < 12; i++) + tm.doLabel(pnlx, pnly + 0 + i * 20, lbl[i]); + tm.doNud(pnlx + 100, pnly + 0, 0, 32); + tm.doNud(pnlx + 100, pnly + 20, 4, 8); //Level + tm.doNud(pnlx + 100, pnly + 40, 5, 8); + tm.doNud(pnlx + 100, pnly + 60, 6, 16); //HP + tm.doNud(pnlx + 100, pnly + 80, 8, 16); //PP + tm.doNud(pnlx + 100, pnly + 100, 10, 16); //Atk + tm.doNud(pnlx + 100, pnly + 120, 12, 16); //Def + tm.doNud(pnlx + 100, pnly + 140, 14, 16); //Agl + tm.doNud(pnlx + 100, pnly + 160, 16, 8); //Lck + tm.doNud(pnlx + 100, pnly + 180, 17, 8); //Turns + tm.doNud(pnlx + 100, pnly + 200, 18, 8); + tm.doNud(pnlx + 100, pnly + 220, 19, 8); + + //Items + tm.doLabel(pnlx + 220, pnly, "Item"); + tm.doNud(pnlx + 220, pnly + 20, 20, 16); + tm.doNud(pnlx + 220, pnly + 40, 22, 16); + tm.doNud(pnlx + 220, pnly + 60, 24, 16); + tm.doNud(pnlx + 220, pnly + 80, 26, 16); + tm.doLabel(pnlx + 340, pnly, "Quantity"); + tm.doNud(pnlx + 340, pnly + 20, 28, 8); + tm.doNud(pnlx + 340, pnly + 40, 29, 8); + tm.doNud(pnlx + 340, pnly + 60, 30, 8); + tm.doNud(pnlx + 340, pnly + 80, 31, 8); + + //Element + //pnlx = ? + pnly = 280; + Label ae = tm.doLabel(pnlx, pnly, "Attack Element"); + //ae.Width = 200; + String[] elements = { "Venus", "Mercury", "Mars", "Jupiter", "Neutral" }; + tm.doCombo(pnlx, pnly + 20, Bits.textToBytes(elements), Bits.numList(5), 0x20, 8); + + tm.doLabel(pnlx + 100, pnly + 60, "Venus"); + tm.doLabel(pnlx + 200, pnly + 60, "Mercury"); + tm.doLabel(pnlx + 300, pnly + 60, "Mars"); + tm.doLabel(pnlx + 400, pnly + 60, "Jupiter"); + + tm.doLabel(pnlx, pnly + 80, "Level"); + tm.doLabel(pnlx, pnly + 100, "Power"); + tm.doLabel(pnlx, pnly + 120, "Resist"); + + tm.doNud(pnlx + 100, pnly + 80, 0x21, 8); + tm.doNud(pnlx + 200, pnly + 80, 0x22, 8); + tm.doNud(pnlx + 300, pnly + 80, 0x23, 8); + tm.doNud(pnlx + 400, pnly + 80, 0x24, 8); + //0x25 = Unused? + tm.doNud(pnlx + 100, pnly + 100, 0x26, 16); + tm.doNud(pnlx + 100, pnly + 120, 0x28, 16); + tm.doNud(pnlx + 200, pnly + 100, 0x2A, 16); + tm.doNud(pnlx + 200, pnly + 120, 0x2C, 16); + tm.doNud(pnlx + 300, pnly + 100, 0x2E, 16); + tm.doNud(pnlx + 300, pnly + 120, 0x30, 16); + tm.doNud(pnlx + 400, pnly + 100, 0x32, 16); + tm.doNud(pnlx + 400, pnly + 120, 0x34, 16); + + } + void loadDjinn(TabControl a)//, TabPage d) + { + TabPage d = a.SelectedTab; + Table_Manager tm = new Table_Manager(); + tm.setTable(ram, 0x61AFC, 0x8); + tm.setPanel(a.SelectedTab);//tabPage6); + int pnlx = d.Width / 2 - 150 + 100 + 25; + int pnly = d.Height / 2 - 125; + //d.Text = "Forge"; + List items = new List();// = {5, 6, 7 }; + items.Add(5); + String[] text = { "" };// "Processed", "Rusted" }; + //tm.doCombo(pnlx + 200, pnly + 20, Bits.textToBytes(text) + tm.doTableListbox(Bits.textToBytes(text), Bits.numList(83)); + tm.doNud(pnlx + 200, pnly + 80, 0, 16); + tm.doNud(pnlx + 200, pnly + 100, 2, 8); + tm.doNud(pnlx + 200, pnly + 120, 3, 8); + tm.doNud(pnlx + 200, pnly + 140, 4, 8); + tm.doNud(pnlx + 200, pnly + 160, 5, 8); + tm.doNud(pnlx + 200, pnly + 180, 6, 8); + tm.doNud(pnlx + 200, pnly + 200, 7, 8); + //tm.loadEntry(); + } + void loadARM9() + { + int romOffset = Bits.getInt32(header, 0x20); + //int entryAddr = Bits.getInt32(header, 0x24); //Where execution starts? + int ramAddr = Bits.getInt32(header, 0x28) & 0x1FFFFFF; + int size = Bits.getInt32(header, 0x2C); + using (FileStream a = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + a.Seek(romOffset, SeekOrigin.Begin); + a.Read(ram, ramAddr, size); + } + int endAddr = Bits.getInt32(ram, 0xB88 + 0x14) & 0x1FFFFFF; + dec1(endAddr);// ramAddr + size); + //return null; + } + void loadFile(int fileID) + { + //if ((fileID < 0) || (fileID >= 0xF000)) + // return; + int ovrA = fileID << 5; + int fatA = fileID << 3; //One of Overlay ID or File ID in ovr should determine this? So update later? + int fat1 = Bits.getInt32(fat, fatA); + int fat2 = Bits.getInt32(fat, fatA + 4); + int size = fat2 - fat1; + byte[] src = Bits.openFilePart(path, fat1, size); //new byte[size]; + + //if (fileID == 0) + // Bits.saveFile(@"C:\Users\Tea\Desktop\original.bin", src); + //Bits.saveFilePart(path, fat1, size, des); + int srcPos = 0; + byte[] des = ram; + //int desPos = Bits.getInt32(ovr, ovrA + 4) & 0x1FFFFFF; + //if (fileID > 0x16D) //Quick hack: If not overlay file.... then I dunno where to put it yet, so... + // desPos = 0x220B80; //Update to base on slot list at 020840D4? + int desPos = 0x220B80; + if (fileID <= 0x16D) + desPos = Bits.getInt32(ovr, ovrA + 4) & 0x1FFFFFF; + //Sample/example - Some empty text files look like this: + //40 04 00 00 A0 FF 13 00 00 00 + //In easier to read format: 40 000004 60 FF 001/3 000/0 + //(Note: -A0 = 60) + //which decompresses to FFFFFFFF. + if (src[srcPos++] != 0x40) + return; + int decSize = src[srcPos++] | (src[srcPos++] << 8) | (src[srcPos++] << 16); + if (decSize == 0) { decSize = Bits.getInt32(src, srcPos); srcPos += 4; } + while (decSize-- > 0) + { + int flags = 0x800000 - (src[srcPos++] << 0x18); + while ((flags << 1) != 0) + { + if (flags > 0) + { + des[desPos++] = src[srcPos++]; + } + else + { + int len = src[srcPos] & 0xF; + int dist = (src[srcPos++] >> 4) | (src[srcPos++] << 4); + if (len == 0) + { + if (dist == 0) //Used by default. + return; + len = 0x10 + src[srcPos++]; + } + else if (len == 1) + { + if (dist == 0) //May not ever be used, but here for functionality. + return; + len = 0x110 + src[srcPos++] + (src[srcPos++] << 8); + } + dist = desPos - dist; + while (len-- > 0) + des[desPos++] = des[dist++]; + } + flags <<= 1; + } + } + } + void saveFile(int fileID) + { + if (fileID > 0x16D) + return; + int ovrA = fileID << 5; + int srcStart = Bits.getInt32(ovr, ovrA + 4) & 0x1FFFFFF; + int srcSize = Bits.getInt32(ovr, ovrA + 8); // & 0x1FFFFFF; + int srcEnd = srcStart + srcSize; + int desSize = srcSize + (srcSize >> 3) + 7; //Absolute maximum possible size... (Including header and end of data command.) + desSize = (desSize + 0x1FF) & -0x200; + byte[] src = ram;// new byte[srcSize]; + int srcPos = srcStart; + byte[] des = new byte[desSize]; + int desPos = 0; + des[desPos++] = 0x40; + des[desPos++] = (byte)srcSize; + des[desPos++] = (byte)(srcSize >> 8); + des[desPos++] = (byte)(srcSize >> 16); + int fCur = 0x80; + int fAddr = desPos++; + int flags = 0; + while (srcPos < srcEnd) + { + int dist = 0; + int len = 0; + int winStart = Math.Max(srcStart, srcPos - 0xFFF); + for (int i = winStart; i < srcPos; i++) + { + for (int j = 1; j < 0x10110; j++) + { + if (src[srcPos + j] == src[i + j]) + { + //if ((j + 1) >= len) + if (j >= len) + { + dist = i; + //len = j + 1; + len = j; + } + } + else + break; + } + if (src[srcPos] == src[i]) + { + len += 1; + } + else + { + dist += 1; + } + } + if (src[srcPos] != src[dist]) //Insert byte + { + des[desPos++] = src[srcPos++]; + fCur >>= 1; + if (fCur == 0) + { + des[fAddr] = (byte)-flags; + fAddr = desPos++; + fCur = 0x80; + flags = 0; + } + } + dist = srcPos - dist; + if (len < 2) + { + des[desPos++] = src[srcPos]; len = 1; + } + else if (len < 0x10) + { + des[desPos++] = (byte)((dist << 4) | len); + des[desPos++] = (byte)(dist >> 4); + } + else if (len < 0x110) + { + des[desPos++] = (byte)((dist << 4) | 0); + des[desPos++] = (byte)(dist >> 4); + des[desPos++] = (byte)(len - 0x10); + } + else // if (len < 0x10110) + { + des[desPos++] = (byte)((dist << 4) | 1); + des[desPos++] = (byte)(dist >> 4); + des[desPos++] = (byte)(len - 0x110); + des[desPos++] = (byte)((len - 0x110) >> 8); + } + srcPos += len; + if (len > 1) + flags |= fCur; + + fCur >>= 1; + if (fCur == 0) + { + des[fAddr] = (byte)-flags; + fAddr = desPos++; + fCur = 0x80; + flags = 0; + } + } + des[desPos++] = 0; + des[desPos++] = 0; + flags |= fCur; + des[fAddr] = (byte)-flags; + + //Now to save to ROM. + Bits.saveFile(@"C:\Users\Tea\Desktop\notoriginal.bin", des); + return; + int fatA = fileID << 3; + int fat1 = Bits.getInt32(fat, fatA); + Bits.setInt32(fat, fatA + 4, fat1 + desPos); + //int fat2 = Bits.getInt32(fat, fatA + 4); + int fat2 = Bits.getInt32(fat, fatA + 8); + int size = fat2 - fat1; + //For neatness.... + while (desPos < size) + { + des[desPos++] = 0xFF; + } + if (desPos != size) + { + MessageBox.Show("About to lose data... Have fun!"); + } + Bits.saveFilePart(path, fat1, size, des); + } + void dec1(int addr)//, int size) //02000950. + { + //if (addr == 0) + // return; + //addr &= 0x1FFFFFF; + + int h1 = Bits.getInt32(ram, addr - 8); + int h2 = Bits.getInt32(ram, addr - 4); + h2 += addr; //h2=destAddr + int r3 = addr - (h1 >> 0x18); //r3=srcAddr + h1 &= 0xFFFFFF; + h1 = addr - h1; //h1=Where to stop decompressing. + + newset: + if (r3 <= h1) + return; + int r5 = ram[--r3]; //r5=flags + int r6 = 0x8; + + nextb: + if (--r6 < 0) + goto newset; + + if ((r5 & 0x80) == 0) //Constant / Distance/Length pair + { + ram[--h2] = ram[--r3]; + } + else + { + int r12 = ram[--r3]; + int r7 = ram[--r3]; + r7 = (((r12 << 8) | r7) & 0xFFF) + 2; + r12 += 0x20; + do + { + ram[h2 - 1] = ram[h2 + r7]; h2--; + r12 -= 0x10; + } while (r12 >= 0); + } + r5 <<= 1; + if (r3 > h1) + goto nextb; + } + + //void dec2() + //0x16E + void doTextFiles() + { + //0xBF7 <0x13D2 + for (int i = 0xBF7; i < 0x13D2; i++) + { + fileid = i; + loadFile(i); + doTextFile(); + } + } + int fileid = 0; + void doTextFile() + { + int address = 0x220B80;// 0x23C310;//int address = 0x17726C; + System.Text.StringBuilder strbuild = new System.Text.StringBuilder(0x1000); + + //int entries = 130; + while (true) + { + int a = Bits.getInt32(ram, address); + if (a == -1) break; + getText(strbuild, ram, address); + strbuild.AppendLine(); + address += 4; + } + //System.IO.File.WriteAllText(@"C:\Users\Tea\Desktop\text.txt", strbuild.ToString()); + string strbstr = strbuild.ToString(); + if (strbstr.Length < 1) + return; + //System.IO.File.WriteAllText("C:\\Users\\Tea\\Desktop\\msg\\" + strbstr.Substring(0, 8) + ".txt", strbstr.ToString()); + string fn = getFilename(fileid); + System.IO.File.WriteAllText("C:\\Users\\Tea\\Desktop\\msg\\" + fn, strbstr.ToString()); + } + string getFilename(int i) + { + string str = ""; + //int addr = Bits.getInt32(fnt, (i - 0x16D) * 4); + int addr = Bits.getInt32(fnt, 0x140); //File 0xBF7+ + //int i2 = 0xBF7; + for (int i2 = 0xBF7; i2 < i; i2++) + { + addr += (fnt[addr] & 0x7F) + 1; + } + for (int size = fnt[addr++] & 0x7F; size > 0; size--) + { + str += (char)fnt[addr++]; + } + return str; + } + void getText(System.Text.StringBuilder strbuild, byte[] buffer, int address) + { + int addr2 = Bits.getInt32(buffer, address) + 0x220B80; + int length = 2000; int pos = addr2 & 0xFFFFFF; + //MessageBox.Show(addr2.ToString("x8")); + while (length-- > 0) + { + int c = Bits.getInt16(buffer, pos); pos += 2; + if (c == 0) + break; + if ((c < 0x100) && (c > 0xF)) + strbuild.Append((char)c); + else + strbuild.Append("["+c.ToString("X4")+"]"); + } + } +} +} diff --git a/Editors.Designer.cs b/Editors.Designer.cs new file mode 100644 index 0000000..962529f --- /dev/null +++ b/Editors.Designer.cs @@ -0,0 +1,260 @@ +namespace gsmagic { + partial class Editors { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabPage1 = new System.Windows.Forms.TabPage(); + this.checkedListBox2 = new System.Windows.Forms.CheckedListBox(); + this.checkedListBox1 = new System.Windows.Forms.CheckedListBox(); + this.listBox1 = new System.Windows.Forms.ListBox(); + this.tabPage2 = new System.Windows.Forms.TabPage(); + this.tabPage3 = new System.Windows.Forms.TabPage(); + this.tabPage4 = new System.Windows.Forms.TabPage(); + this.tabPage5 = new System.Windows.Forms.TabPage(); + this.tabPage6 = new System.Windows.Forms.TabPage(); + this.tabPage7 = new System.Windows.Forms.TabPage(); + this.tabPage8 = new System.Windows.Forms.TabPage(); + this.tabPage9 = new System.Windows.Forms.TabPage(); + this.tabPage10 = new System.Windows.Forms.TabPage(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.tabControl1.SuspendLayout(); + this.tabPage1.SuspendLayout(); + this.tabPage10.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // tabControl1 + // + this.tabControl1.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.tabControl1.Controls.Add(this.tabPage1); + this.tabControl1.Controls.Add(this.tabPage2); + this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Controls.Add(this.tabPage4); + this.tabControl1.Controls.Add(this.tabPage5); + this.tabControl1.Controls.Add(this.tabPage6); + this.tabControl1.Controls.Add(this.tabPage7); + this.tabControl1.Controls.Add(this.tabPage8); + this.tabControl1.Controls.Add(this.tabPage9); + this.tabControl1.Controls.Add(this.tabPage10); + this.tabControl1.Location = new System.Drawing.Point(1, 2); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(784, 558); + this.tabControl1.TabIndex = 0; + this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabIndexChange); + // + // tabPage1 + // + this.tabPage1.Controls.Add(this.checkedListBox2); + this.tabPage1.Controls.Add(this.checkedListBox1); + this.tabPage1.Controls.Add(this.listBox1); + this.tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(776, 532); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = "Items"; + this.tabPage1.UseVisualStyleBackColor = true; + // + // checkedListBox2 + // + this.checkedListBox2.FormattingEnabled = true; + this.checkedListBox2.Items.AddRange(new object[] { + "Isaac", + "Garet", + "Ivan", + "Mia", + "Felix", + "Jenna", + "Sheba", + "Piers"}); + this.checkedListBox2.Location = new System.Drawing.Point(190, 275); + this.checkedListBox2.Name = "checkedListBox2"; + this.checkedListBox2.Size = new System.Drawing.Size(212, 124); + this.checkedListBox2.TabIndex = 2; + // + // checkedListBox1 + // + this.checkedListBox1.FormattingEnabled = true; + this.checkedListBox1.Items.AddRange(new object[] { + "Curses when equipped", + "Can\'t be removed", + "A rare item", + "An important item", + "Carry up to 30", + "GS2: Can\'t be transferred from GS1", + "Unused", + "Unused"}); + this.checkedListBox1.Location = new System.Drawing.Point(190, 145); + this.checkedListBox1.Name = "checkedListBox1"; + this.checkedListBox1.Size = new System.Drawing.Size(212, 124); + this.checkedListBox1.TabIndex = 1; + // + // listBox1 + // + this.listBox1.Font = new System.Drawing.Font("Lucida Console", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 11; + this.listBox1.Location = new System.Drawing.Point(4, 5); + this.listBox1.Name = "listBox1"; + this.listBox1.Size = new System.Drawing.Size(180, 521); + this.listBox1.TabIndex = 0; + // + // tabPage2 + // + this.tabPage2.Location = new System.Drawing.Point(4, 22); + this.tabPage2.Name = "tabPage2"; + this.tabPage2.Padding = new System.Windows.Forms.Padding(3); + this.tabPage2.Size = new System.Drawing.Size(776, 532); + this.tabPage2.TabIndex = 1; + this.tabPage2.Text = "Artifacts"; + this.tabPage2.UseVisualStyleBackColor = true; + // + // tabPage3 + // + this.tabPage3.Location = new System.Drawing.Point(4, 22); + this.tabPage3.Name = "tabPage3"; + this.tabPage3.Padding = new System.Windows.Forms.Padding(3); + this.tabPage3.Size = new System.Drawing.Size(776, 532); + this.tabPage3.TabIndex = 2; + this.tabPage3.Text = "Shops"; + this.tabPage3.UseVisualStyleBackColor = true; + // + // tabPage4 + // + this.tabPage4.Location = new System.Drawing.Point(4, 22); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Padding = new System.Windows.Forms.Padding(3); + this.tabPage4.Size = new System.Drawing.Size(776, 532); + this.tabPage4.TabIndex = 3; + this.tabPage4.Text = "Abilities"; + this.tabPage4.UseVisualStyleBackColor = true; + // + // tabPage5 + // + this.tabPage5.Location = new System.Drawing.Point(4, 22); + this.tabPage5.Name = "tabPage5"; + this.tabPage5.Padding = new System.Windows.Forms.Padding(3); + this.tabPage5.Size = new System.Drawing.Size(776, 532); + this.tabPage5.TabIndex = 4; + this.tabPage5.Text = "Party"; + this.tabPage5.UseVisualStyleBackColor = true; + // + // tabPage6 + // + this.tabPage6.Location = new System.Drawing.Point(4, 22); + this.tabPage6.Name = "tabPage6"; + this.tabPage6.Padding = new System.Windows.Forms.Padding(3); + this.tabPage6.Size = new System.Drawing.Size(776, 532); + this.tabPage6.TabIndex = 5; + this.tabPage6.Text = "Classes"; + this.tabPage6.UseVisualStyleBackColor = true; + // + // tabPage7 + // + this.tabPage7.Location = new System.Drawing.Point(4, 22); + this.tabPage7.Name = "tabPage7"; + this.tabPage7.Padding = new System.Windows.Forms.Padding(3); + this.tabPage7.Size = new System.Drawing.Size(776, 532); + this.tabPage7.TabIndex = 6; + this.tabPage7.Text = "Djinn/Summons"; + this.tabPage7.UseVisualStyleBackColor = true; + // + // tabPage8 + // + this.tabPage8.Location = new System.Drawing.Point(4, 22); + this.tabPage8.Name = "tabPage8"; + this.tabPage8.Padding = new System.Windows.Forms.Padding(3); + this.tabPage8.Size = new System.Drawing.Size(776, 532); + this.tabPage8.TabIndex = 7; + this.tabPage8.Text = "Enemies/Groups"; + this.tabPage8.UseVisualStyleBackColor = true; + // + // tabPage9 + // + this.tabPage9.Location = new System.Drawing.Point(4, 22); + this.tabPage9.Name = "tabPage9"; + this.tabPage9.Padding = new System.Windows.Forms.Padding(3); + this.tabPage9.Size = new System.Drawing.Size(776, 532); + this.tabPage9.TabIndex = 8; + this.tabPage9.Text = "Text Editor"; + this.tabPage9.UseVisualStyleBackColor = true; + // + // tabPage10 + // + this.tabPage10.Controls.Add(this.pictureBox1); + this.tabPage10.Location = new System.Drawing.Point(4, 22); + this.tabPage10.Name = "tabPage10"; + this.tabPage10.Padding = new System.Windows.Forms.Padding(3); + this.tabPage10.Size = new System.Drawing.Size(776, 532); + this.tabPage10.TabIndex = 9; + this.tabPage10.Text = "tabPage10"; + this.tabPage10.UseVisualStyleBackColor = true; + // + // pictureBox1 + // + this.pictureBox1.Location = new System.Drawing.Point(7, 6); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(760, 512); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // Editors + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(784, 561); + this.Controls.Add(this.tabControl1); + this.Name = "Editors"; + this.Text = "Editors"; + this.Load += new System.EventHandler(this.Editors_Load); + this.tabControl1.ResumeLayout(false); + this.tabPage1.ResumeLayout(false); + this.tabPage10.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabPage1; + private System.Windows.Forms.TabPage tabPage2; + private System.Windows.Forms.TabPage tabPage3; + private System.Windows.Forms.TabPage tabPage4; + private System.Windows.Forms.TabPage tabPage5; + private System.Windows.Forms.TabPage tabPage6; + private System.Windows.Forms.TabPage tabPage7; + private System.Windows.Forms.TabPage tabPage8; + private System.Windows.Forms.TabPage tabPage9; + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.CheckedListBox checkedListBox1; + private System.Windows.Forms.CheckedListBox checkedListBox2; + private System.Windows.Forms.TabPage tabPage10; + private System.Windows.Forms.PictureBox pictureBox1; + } +} \ No newline at end of file diff --git a/Editors.cs b/Editors.cs new file mode 100644 index 0000000..24386d5 --- /dev/null +++ b/Editors.cs @@ -0,0 +1,354 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace gsmagic { + public partial class Editors : Form { + public Editors() { + InitializeComponent(); + } + int[] list = null; //Call save with this. + public Form1 test; + //public byte[] rom;// = Form1.rom; + public byte[] txt; + private System.Windows.Forms.TabControl tabControl01; + subeditor[] subEditor = null;//{ new eClass() }; + private void Editors_Load(object sender, EventArgs e) { + Globals.editorsForm = this; + System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); + txt = Comp.decompText(test.rom); + this.tabControl1.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.tabControl1.Controls.Add(this.tabPage1); + //this.tabControl1.Controls.Add(this.tabPage2); + //this.tabControl1.Controls.Add(this.tabPage3); + //this.tabControl1.Controls.Add(this.tabPage4); + //this.tabControl1.Controls.Add(this.tabPage5); + //this.tabControl1.Controls.Add(this.tabPage6); + //this.tabControl1.Controls.Add(this.tabPage7); + //this.tabControl1.Controls.Add(this.tabPage8); + //this.tabControl1.Controls.Add(this.tabPage9); + //this.tabControl1.Controls.Add(this.tabPage10); + this.tabControl1.Location = new System.Drawing.Point(1, 2); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size(784, 558); + this.tabControl1.TabIndex = 0; + this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabIndexChange); + // + // tabPage1 + // + //this.tabPage1.Controls.Add(this.checkedListBox2); + //this.tabPage1.Controls.Add(this.checkedListBox1); + //this.tabPage1.Controls.Add(this.listBox1); + subeditor[] subEditor = { new eClass() };//subEditor = new eClass(); + tabPage1.Location = new System.Drawing.Point(4, 22); + this.tabPage1.Name = "tabPage1"; + this.tabPage1.Padding = new System.Windows.Forms.Padding(3); + this.tabPage1.Size = new System.Drawing.Size(776, 532); + this.tabPage1.TabIndex = 0; + this.tabPage1.Text = subEditor[0].text(); + this.tabPage1.UseVisualStyleBackColor = true; + + //tabPage8.SuspendLayout(); +// initRandEnctrs(); //Make sure TextEditorLoad stays before this... (for now) +// initEleTable(); //Quick test for now! +// initForgeTable(); +// initClassTable(); + //tabControl1.SelectedIndex = 1; + //tabPage8.ResumeLayout(); + //DateTime a = DateTime.Now; + //byte[] des = new byte[0x8000]; int b = 0; + //for (int i = 0x680000 + (1609 * 4); i < 0x680000 + (1723 * 4); i += 4) { + // Comp.decompress(test.rom, Bits.getInt32(test.rom, i) & 0x1FFFFFF, des, 0); b++; + //} + //Console.WriteLine(DateTime.Now - a + " " + b); //~0.018-0.020 + sw.Stop(); + + Console.WriteLine(sw.Elapsed + " (Editors Load)"); //Slow because of comboboxes AddRange? + } + int tabFlags = 0; + + private void tabIndexChange(object sender, EventArgs e) + { + //Next three lines b/c I don't want to dispose anything, or renew anything? :P (Also keeps selected items where they are until you close the form.) + if ((tabFlags & (1 << ((TabControl)sender).SelectedIndex)) != 0) + return; + tabFlags |= (1 << ((TabControl)sender).SelectedIndex); + switch (((TabControl)sender).SelectedIndex) + { + case 7: + initRandEnctrs(); + break; + case 6: + initEleTable(); + break; + case 5: + initForgeTable(); + break; + case 4: + //initClassTable(); + subeditor a = new eClass(); + a.load(tabControl1); + break; + case 1: + texteditor(); + break; + } + } + public void initForgeTable() { + Table_Manager tm = new Table_Manager(); + tm.setTable(test.rom, 0x10CC34, 0x24); + tm.setPanel(tabControl1.SelectedTab);//tabPage6); + tabPage6.Text = "Forge"; + + //ListBox lstb = tm.doTableListbox(); + ////607 + int ind3 = 0; + List items = new List(); + while (true) //for (int ind3 = 0; ind3 < 0x14; ind3++) + { + //int ind2 = Bits.getInt16(test.rom, 0xEDACC + 4 + ind3 * 0x1C); + int ind = Bits.getInt16(test.rom, 0x10CC34 + ind3 * 0x24); + if (ind == 0xFFFF) { break; } + //StringBuilder str = new StringBuilder(0x200); + //str.Append((ind3).ToString().PadLeft(3, ' ') + "|"); + //items.Add((ind3).ToString().PadLeft(3, ' ') + "|" + getTextStrShort(607 + ind)); + items.Add(607 + ind); + ind3++; + } + tm.doTableListbox(txt, items);// items); + String[] itemNames = new String[461]; + for (int ind2 = 0; ind2 < 461; ind2++) + { + itemNames[ind2] = ind2.ToString().PadLeft(3, ' ') + "|" + Bits.getTextShort(txt, 607 + ind2); + } + int pnlx = tabPage8.Width / 2 - 150 + 100 + 25; + int pnly = tabPage8.Height / 2 - 125; + Label fi = tm.doLabel(pnlx, pnly, "Forgeable Item"); + //fi.Width = 200; + tm.doCombo(pnlx, pnly + 20, Bits.textToBytes(itemNames), Bits.numList(461), 0, 16); + tm.doLabel(pnlx + 200, pnly, "Just text?"); + String[] text = { "Processed", "Rusted" }; + tm.doCombo(pnlx + 200, pnly + 20, Bits.textToBytes(text), Bits.numList(2), 2, 16); + //fi.Width = 200; + //tm.doNud(pnlx+ 200, pnly + 20, 2, 16); + + tm.doLabel(pnlx, pnly+60, "Item"); + tm.doLabel(pnlx + 200, pnly+60, "Rate"); + + tm.doCombo(pnlx, pnly + 80, Bits.textToBytes(itemNames), Bits.numList(461), 4, 16); + tm.doCombo(pnlx, pnly + 100, Bits.textToBytes(itemNames), Bits.numList(461), 6, 16); + tm.doCombo(pnlx, pnly + 120, Bits.textToBytes(itemNames), Bits.numList(461), 8, 16); + tm.doCombo(pnlx, pnly + 140, Bits.textToBytes(itemNames), Bits.numList(461), 10, 16); + tm.doCombo(pnlx, pnly + 160, Bits.textToBytes(itemNames), Bits.numList(461), 12, 16); + tm.doCombo(pnlx, pnly + 180, Bits.textToBytes(itemNames), Bits.numList(461), 14, 16); + tm.doCombo(pnlx, pnly + 200, Bits.textToBytes(itemNames), Bits.numList(461), 16, 16); + tm.doCombo(pnlx, pnly + 220, Bits.textToBytes(itemNames), Bits.numList(461), 18, 16); + + tm.doNud(pnlx + 200, pnly + 80, 20, 16); + tm.doNud(pnlx + 200, pnly + 100, 22, 16); + tm.doNud(pnlx + 200, pnly + 120, 24, 16); + tm.doNud(pnlx + 200, pnly + 140, 26, 16); + tm.doNud(pnlx + 200, pnly + 160, 28, 16); + tm.doNud(pnlx + 200, pnly + 180, 30, 16); + tm.doNud(pnlx + 200, pnly + 200, 32, 16); + tm.doNud(pnlx + 200, pnly + 220, 34, 16); + + //lstb.SelectedIndex = 0; + } + private void initEleTable() { + Table_Manager tm = new Table_Manager(); + tm.setTable(test.rom, 0xC6684, 0x18); + tm.setPanel(tabControl1.SelectedTab);//tabPage7); + tabPage7.Text = "Elemental Data"; + + //ListBox lstb = tm.doTableListbox(); + List items = new List(); + //Determine what should go in table's Listbox + int[] elni = new int[48]; + for (int ind3 = 0; ind3 < 379; ind3++) + { + if (elni[test.rom[0xB9E7C + ind3 * 0x4C + 0x2A]] == 0) + { + elni[test.rom[0xB9E7C + ind3 * 0x4C + 0x2A]] = ind3+1; + } + } + //Populate the Listbox + for (int ind3 = 0; ind3 < 48; ind3++) { + + if (elni[ind3] == 0) { + //items.Add((ind3).ToString().PadLeft(3, ' ') + "|"); + items.Add(-1); + continue; + } + //items.Add((ind3).ToString().PadLeft(3, ' ') + "|" + getTextStrShort(1068 + elni[ind3]-1)); + items.Add(1068 + elni[ind3] - 1); + } + tm.doTableListbox(txt, items); + + int pnlx = tabPage8.Width / 2 - 150 + 25;// + 100; + int pnly = tabPage8.Height / 2 - 125; + + Label ae = tm.doLabel(pnlx, pnly, "Attack Element"); + //ae.Width = 200; + String[] elements = { "Venus", "Mercury", "Mars", "Jupiter", "Neutral" }; + tm.doCombo(pnlx, pnly + 20, Bits.textToBytes(elements), Bits.numList(5), 0, 32); + + tm.doLabel(pnlx+100, pnly+60, "Venus"); + tm.doLabel(pnlx+200, pnly+60, "Mercury"); + tm.doLabel(pnlx+300, pnly+60, "Mars"); + tm.doLabel(pnlx+400, pnly+60, "Jupiter"); + + tm.doLabel(pnlx, pnly+80, "Level"); + tm.doLabel(pnlx, pnly+100, "Power"); + tm.doLabel(pnlx, pnly+120, "Resist"); + + tm.doNud(pnlx + 100, pnly + 80, 4, 8); + tm.doNud(pnlx + 200, pnly + 80, 5, 8); + tm.doNud(pnlx + 300, pnly + 80, 6, 8); + tm.doNud(pnlx + 400, pnly + 80, 7, 8); + + tm.doNud(pnlx + 100, pnly + 100, 8, 16); + tm.doNud(pnlx + 100, pnly + 120, 10, 16); + tm.doNud(pnlx + 200, pnly + 100, 12, 16); + tm.doNud(pnlx + 200, pnly + 120, 14, 16); + tm.doNud(pnlx + 300, pnly + 100, 16, 16); + tm.doNud(pnlx + 300, pnly + 120, 18, 16); + tm.doNud(pnlx + 400, pnly + 100, 20, 16); + tm.doNud(pnlx + 400, pnly + 120, 22, 16); + + //lstb.SelectedIndex = 0; + } + //Random Encounters + private void initRandEnctrs() { + Table_Manager tm = new Table_Manager(); + tm.setTable(test.rom, 0xEDACC, 0x1C); + tm.setPanel(tabControl1.SelectedTab);//tabPage8); + tabPage8.Text = "Encounters"; + + List items = new List(); + //ListBox lstb = tm.doTableListbox(); + for (int ind3 = 0; ind3 < 0x6E; ind3++) + { + int ind2 = Bits.getInt16(test.rom, 0xEDACC + 4 + ind3 * 0x1C); + int ind = Bits.getInt16(test.rom, 0x12CE7C + ind2 * 0x18); + //StringBuilder str = new StringBuilder(0x200); + //str.Append((ind3).ToString().PadLeft(3, ' ') + "|"); + //items.Add((ind3).ToString().PadLeft(3, ' ') + "|" + getTextStrShort(1068 + ind)); + items.Add(1068 + ind); + } + tm.doTableListbox(txt, items); //items); + + int pnlx = tabPage8.Width / 2 - 150 + 100 + 25; + int pnly = tabPage8.Height / 2 - 125; + + tm.doLabel(pnlx, pnly, "Frequency"); + tm.doNud(pnlx, pnly + 20, 0, 16); + tm.doLabel(pnlx + 200, pnly, "Target Level"); + tm.doNud(pnlx + 200, pnly + 20, 2, 16); + + + tm.doLabel(pnlx, pnly + 60, "Group"); + tm.doLabel(pnlx + 200, pnly + 60, "Rate"); + String[] enGroups = new String[660]; + for (int ind2 = 0; ind2 < 660; ind2++) + { + enGroups[ind2] = ind2.ToString().PadLeft(3, ' ') + "|" + Bits.getTextShort(txt, 1068 + Bits.getInt16(test.rom, 0x12CE7C + ind2 * 0x18)); + } + tm.doCombo(pnlx, pnly + 80, Bits.textToBytes(enGroups), Bits.numList(660), 4,16); + tm.doCombo(pnlx, pnly + 100, Bits.textToBytes(enGroups), Bits.numList(660), 6,16); + tm.doCombo(pnlx, pnly + 120, Bits.textToBytes(enGroups), Bits.numList(660), 8,16); + tm.doCombo(pnlx, pnly + 140, Bits.textToBytes(enGroups), Bits.numList(660), 10,16); + tm.doCombo(pnlx, pnly + 160, Bits.textToBytes(enGroups), Bits.numList(660), 12,16); + tm.doCombo(pnlx, pnly + 180, Bits.textToBytes(enGroups), Bits.numList(660), 14,16); + tm.doCombo(pnlx, pnly + 200, Bits.textToBytes(enGroups), Bits.numList(660), 16,16); + tm.doCombo(pnlx, pnly + 220, Bits.textToBytes(enGroups), Bits.numList(660), 18,16); + + tm.doNud(pnlx + 200, pnly + 80,20,8); + tm.doNud(pnlx + 200, pnly + 100,21,8); + tm.doNud(pnlx + 200, pnly + 120,22,8); + tm.doNud(pnlx + 200, pnly + 140,23,8); + tm.doNud(pnlx + 200, pnly + 160,24,8); + tm.doNud(pnlx + 200, pnly + 180,25,8); + tm.doNud(pnlx + 200, pnly + 200,26,8); + tm.doNud(pnlx + 200, pnly + 220,27,8); + + //lstb.SelectedIndex = 0; + } + private void dispAllIcons() { + DateTime a = DateTime.Now; + //this.Show(); + //byte[] img = Comp.decompress16All(test.rom, 0x4eb58);//Comp.decompress16(test.rom, 0x0804F128 & 0x1FFFFFF, 0); + //byte[] img = Comp.decompress16All(test.rom, 0x54A14); + //byte[] img = Comp.decompress16All(test.rom, 0x58ff4); + //Will load pal from ROM later. + //int[] pal = { 0x0000, 0x0000, 0x001F, 0x01DF, 0x03FF, 0x03E0, 0x1DC7, 0x7FE0, 0x7C00, 0x59DC, 0x3ADF, 0x01D6, 0x000E, 0x1CE7, 0x4E73, 0x7FFF }; + int[] pal = { 0x000000, 0x000000, 0xf80000, 0xf87000, 0xf8f800, 0x00f800, 0x387038, 0x00f8f8, 0x0000f8, 0xE070B0, 0xF8B070, 0xb07000, 0x700000, 0x383838, 0x989898, 0xf8f8f8 }; + //int[] pal = null;//{ 0x00ffffff }; //, 0x7fffffff,0x7fffffff, 0x7fffffff }; + int tilePal = 0;//(tile >> 8) & 0xF0; + int scnw = 16*32, scnh = 16*32, t2 = 0, row=0; + int[] bmpdata = new int[scnw*scnh];//img.Length]; + int[] ilist = { 0x4eb58, 0x54A14, 0x58ff4 }; + for (int i = 0; i < 3; i++) { + byte[] img = Comp.decompress16All(test.rom, ilist[i]); + for (int r = row; r < scnh; r += 16) { + row += 16; + for (int c = 0; c < scnw; c += 16) { + if (t2 >= img.Length) { goto nextList; } + for (int y = r; y <= r + 15; y++) { + int ry = y;// if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + //int pix = ram.getInt32(pos); pos += 4; + for (int x = c; x <= c + 15; x++) { //x += 2) { + int rx = x; //if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + int pix = img[t2++]; + int pix2 = pix & 0xF; + if (pix2 != 0) { + bmpdata[(ry * scnw) + rx] = pal[tilePal | (pix2)]; + //priomap[(ry * bitmapWidth) + rx] = priority; + } + //pix >>= 4; + //rx = x + 1; //if ((tile & 0x400) != 0) { rx = c + ((7 - (x + 1)) & 7); } //Horr. flip + //pix2 = pix >> 4; + //if (pix2 != 0) { + // bmpdata[(ry * scnw) + rx] = pal[tilePal | (pix2)]; + // //priomap[(ry * bitmapWidth) + rx] = priority; + //} + //pix >>= 4; + } + } + } + } + nextList: t2 = 0; row += 16; + } + //Add image to picbox. + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/imgtest.dmp", img); + pictureBox1.Image = Form1.PixelsToImage(bmpdata, scnw, scnh); + Console.WriteLine(DateTime.Now - a); + } + + private void texteditor() { + TabPage tp = tabControl1.SelectedTab; + int w = tp.Width; + int h = tp.Height; + Table_Manager tm = new Table_Manager(); + tm.setPanel(tp); + tp.Text = "Text Editor"; + tm.doTableListbox(txt, Bits.numList(12461)); + tm.sl.tb.Bounds = new Rectangle(0, 120, w, 20); + tm.sl.lv.Bounds = new Rectangle(0, 140, w, h - 140); + + DataTextbox dtb = tm.doNamebox(0, 0, txt, 0); + dtb.tbx.Bounds = new Rectangle(0, 0, w - 100, 120); + dtb.tbx.Multiline = true; + dtb.bn.Bounds = new Rectangle(w - 100, 0, 100, 120); + } + } +} diff --git a/Editors.resx b/Editors.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Editors.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Form1.Designer.cs b/Form1.Designer.cs new file mode 100644 index 0000000..fd878a7 --- /dev/null +++ b/Form1.Designer.cs @@ -0,0 +1,343 @@ +namespace gsmagic { + partial class Form1 { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing && (components != null)) { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.panel1 = new System.Windows.Forms.Panel(); + this.toolStripButton3 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton2 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this.nextMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.previousMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButton4 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton5 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton6 = new System.Windows.Forms.ToolStripButton(); + this.toolStripButton7 = new System.Windows.Forms.ToolStripButton(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); + this.editorsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.panel1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.Location = new System.Drawing.Point(0, 0); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(720, 640); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.mapClick); + this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.mapClick); + // + // panel1 + // + this.panel1.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.panel1.AutoScroll = true; + this.panel1.BackColor = System.Drawing.SystemColors.Control; + this.panel1.Controls.Add(this.pictureBox1); + this.panel1.Location = new System.Drawing.Point(0, 49); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(784, 513); + this.panel1.TabIndex = 6; + // + // toolStripButton3 + // + this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton3.Name = "toolStripButton3"; + this.toolStripButton3.Size = new System.Drawing.Size(23, 19); + this.toolStripButton3.Text = "L3"; + // + // toolStripButton2 + // + this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton2.Name = "toolStripButton2"; + this.toolStripButton2.Size = new System.Drawing.Size(23, 19); + this.toolStripButton2.Text = "L2"; + // + // toolStripButton1 + // + this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton1.Name = "toolStripButton1"; + this.toolStripButton1.Size = new System.Drawing.Size(23, 19); + this.toolStripButton1.Text = "L1"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.openToolStripMenuItem.Size = new System.Drawing.Size(203, 22); + this.openToolStripMenuItem.Text = "Open..."; + // + // saveToolStripMenuItem + // + this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.saveToolStripMenuItem.Size = new System.Drawing.Size(203, 22); + this.saveToolStripMenuItem.Text = "Save"; + // + // saveAsToolStripMenuItem + // + this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; + this.saveAsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.S))); + this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(203, 22); + this.saveAsToolStripMenuItem.Text = "Save As..."; + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(200, 6); + // + // nextMapToolStripMenuItem + // + this.nextMapToolStripMenuItem.Name = "nextMapToolStripMenuItem"; + this.nextMapToolStripMenuItem.ShortcutKeyDisplayString = "Pg-Up"; + this.nextMapToolStripMenuItem.Size = new System.Drawing.Size(203, 22); + this.nextMapToolStripMenuItem.Text = "Next map"; + // + // previousMapToolStripMenuItem + // + this.previousMapToolStripMenuItem.Name = "previousMapToolStripMenuItem"; + this.previousMapToolStripMenuItem.ShortcutKeyDisplayString = "Pg-Down"; + this.previousMapToolStripMenuItem.Size = new System.Drawing.Size(203, 22); + this.previousMapToolStripMenuItem.Text = "Previous map"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.saveToolStripMenuItem, + this.saveAsToolStripMenuItem, + this.toolStripSeparator1, + this.nextMapToolStripMenuItem, + this.previousMapToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "File"; + // + // toolStrip1 + // + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButton4, + this.toolStripButton5, + this.toolStripButton6, + this.toolStripButton7}); + this.toolStrip1.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow; + this.toolStrip1.Location = new System.Drawing.Point(0, 24); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(784, 22); + this.toolStrip1.TabIndex = 7; + this.toolStrip1.Text = "toolStrip1"; + // + // toolStripButton4 + // + this.toolStripButton4.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton4.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton4.Image"))); + this.toolStripButton4.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton4.Name = "toolStripButton4"; + this.toolStripButton4.Size = new System.Drawing.Size(23, 19); + this.toolStripButton4.Text = "L1"; + // + // toolStripButton5 + // + this.toolStripButton5.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton5.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton5.Image"))); + this.toolStripButton5.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton5.Name = "toolStripButton5"; + this.toolStripButton5.Size = new System.Drawing.Size(23, 19); + this.toolStripButton5.Text = "L2"; + // + // toolStripButton6 + // + this.toolStripButton6.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton6.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton6.Image"))); + this.toolStripButton6.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton6.Name = "toolStripButton6"; + this.toolStripButton6.Size = new System.Drawing.Size(23, 19); + this.toolStripButton6.Text = "L3"; + // + // toolStripButton7 + // + this.toolStripButton7.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButton7.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton7.Image"))); + this.toolStripButton7.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButton7.Name = "toolStripButton7"; + this.toolStripButton7.Size = new System.Drawing.Size(186, 19); + this.toolStripButton7.Text = "Compress tilemap to ROM buffer"; + this.toolStripButton7.Click += new System.EventHandler(this.toolStripButton7_Click); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem1, + this.editorsToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.menuStrip1.Size = new System.Drawing.Size(784, 24); + this.menuStrip1.TabIndex = 8; + this.menuStrip1.Text = "menuStrip1"; + this.menuStrip1.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.menuStrip1_ItemClicked); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripMenuItem2, + this.toolStripMenuItem3, + this.toolStripMenuItem4, + this.toolStripSeparator2, + this.toolStripMenuItem5, + this.toolStripMenuItem6}); + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(37, 20); + this.toolStripMenuItem1.Text = "File"; + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.toolStripMenuItem2.Size = new System.Drawing.Size(203, 22); + this.toolStripMenuItem2.Text = "Open..."; + this.toolStripMenuItem2.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.toolStripMenuItem3.Size = new System.Drawing.Size(203, 22); + this.toolStripMenuItem3.Text = "Save"; + this.toolStripMenuItem3.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); + // + // toolStripMenuItem4 + // + this.toolStripMenuItem4.Name = "toolStripMenuItem4"; + this.toolStripMenuItem4.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.S))); + this.toolStripMenuItem4.Size = new System.Drawing.Size(203, 22); + this.toolStripMenuItem4.Text = "Save As..."; + this.toolStripMenuItem4.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(200, 6); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.ShortcutKeyDisplayString = "Pg-Up"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(203, 22); + this.toolStripMenuItem5.Text = "Next map"; + this.toolStripMenuItem5.Click += new System.EventHandler(this.nextMapToolStripMenuItem_Click); + // + // toolStripMenuItem6 + // + this.toolStripMenuItem6.Name = "toolStripMenuItem6"; + this.toolStripMenuItem6.ShortcutKeyDisplayString = "Pg-Down"; + this.toolStripMenuItem6.Size = new System.Drawing.Size(203, 22); + this.toolStripMenuItem6.Text = "Previous map"; + this.toolStripMenuItem6.Click += new System.EventHandler(this.previousMapToolStripMenuItem_Click); + // + // editorsToolStripMenuItem + // + this.editorsToolStripMenuItem.Name = "editorsToolStripMenuItem"; + this.editorsToolStripMenuItem.Size = new System.Drawing.Size(55, 20); + this.editorsToolStripMenuItem.Text = "Editors"; + this.editorsToolStripMenuItem.Click += new System.EventHandler(this.editorsToolStripMenuItem_Click); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(784, 561); + this.Controls.Add(this.toolStrip1); + this.Controls.Add(this.menuStrip1); + this.Controls.Add(this.panel1); + this.Name = "Form1"; + this.Text = "Form1"; + this.Load += new System.EventHandler(this.Form1_Load); + this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.panel1.ResumeLayout(false); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ToolStripButton toolStripButton3; + private System.Windows.Forms.ToolStripButton toolStripButton2; + private System.Windows.Forms.ToolStripButton toolStripButton1; + private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; + private System.Windows.Forms.ToolStripMenuItem nextMapToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem previousMapToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.ToolStripButton toolStripButton4; + private System.Windows.Forms.ToolStripButton toolStripButton5; + private System.Windows.Forms.ToolStripButton toolStripButton6; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem4; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem5; + private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem6; + private System.Windows.Forms.ToolStripMenuItem editorsToolStripMenuItem; + private System.Windows.Forms.ToolStripButton toolStripButton7; + } +} + diff --git a/Form1.cs b/Form1.cs new file mode 100644 index 0000000..fe766ff --- /dev/null +++ b/Form1.cs @@ -0,0 +1,2474 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; //Bitmap /May later need for Rectangle as well. +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +//using System.Drawing; //Bitmap/Rectangle +using System.Drawing.Imaging; //PixelFormat +using System.Runtime.InteropServices; //Marshal + +namespace gsmagic { + public partial class Form1 : Form { + public Form1() { + InitializeComponent(); + } + string sayHi() { //WIP - Can be used for alerts/etc. but only used for form's title bar at the moment. + string[] greeting = { + "Hi", "Hey", "Hello" + }; + int rng = new Random().Next(3); + return greeting[rng] + " " + Environment.UserName + "!"; + } + void creativeTitle() { + string[] greeting = { + sayHi(), //Used for default message. (After the below messages are done.) And given the rng, it's not the same everytime! + "Hello! Welcome to GSM! Nice to meet you!", + "Hey there! What's your name again? Was it {0}? Welcome back!", + "Hey {0}! I think I finally got your name now. What's up?", + "Hey {0}! How's the hacking going?", + + "You sure do love to hack, don't you {0}?" + + }; + int runs = Properties.Settings.Default.Runs; + if (runs < 20000) runs += 1; + Properties.Settings.Default.Runs = runs; + Properties.Settings.Default.Save(); + if (runs >= greeting.Length) { runs = 0; }//-= 1; + Text = "GSM: " + string.Format(greeting[runs], Environment.UserName); + } + //Form load > Open/Save ROM + private void Form1_Load(object sender, EventArgs e) { + // An attempt to find out how many random seeds there are.... but it didn't work. + //byte[] a = new byte[0x20000000]; + //ulong seed = 0; + //int num = 0; + ////a[seed] = (uint)(a[seed] & ~((uint)1 << ((int)seed & 7)) | ((uint)1 << ((int)seed & 7)); + //while (((a[seed >> 3] >> (int)(seed & 7)) & 1) == 0) + //{ + // a[seed >> 3] |= (byte)(1 << ((int)(seed & 7))); + // seed = (uint)((ulong)1103515245 * seed + 12345); + // num++; + //} + //MessageBox.Show(num.ToString("X8") + " " + seed.ToString("X8")); + //return; + Globals.mainForm = this; //Makes it easy to reference this form everywhere. (Not sure of best method?) + //Dark_Dawn test = new Dark_Dawn(); + //test.extract(); + + //Console.WriteLine("UserName: {0}", Environment.UserName); + //Console.WriteLine(System.Windows.Forms.SystemInformation.UserName); + //MessageBox.Show((unchecked((ulong)-1)<<0x40).ToString("X16")); + //byte[] ba = {7,7,7,7}; + //System.Media.SoundPlayer test = new System.Media.SoundPlayer(new MemoryStream(ba)); + //test. + if (System.IO.File.Exists(Properties.Settings.Default.LastRom)) { OpenROM(Properties.Settings.Default.LastRom); } else { OpenROMdialogue(); } + creativeTitle(); + //DateTime a = DateTime.Now;//.Ticks; + //byte[] t = decompress(rom, 0xA8B1B8, 0); //Format 2 + //byte[] t = decompress(rom, 0x888FE4 + 0x80, 0); //Format 2 + //byte[] t = decompress16(rom, 0x4F157, 0); //Format 2 + //byte[] t = decompText(rom, 0x111); // decompBtlBG(rom, 0x7765D8 + 0x100); + //byte[] t = decompText(rom); + //comptext(t, rom);; + //Editors a = new Editors(); + //a.Show(); + //a.tabControl = 0; + //a.rom = rom; + //DateTime c = DateTime.Now;//.Ticks; + //Console.WriteLine((c - a).ToString()); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/gsdtest.dmp", t); + //DateTime a = DateTime.Now;//.Ticks; + //loadEntireMap(); + //DateTime c = DateTime.Now;//.Ticks; + //Console.WriteLine((c - a).ToString()); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/gsdtest2.dmp", decompText(rom)); + } + private void OpenROMdialogue() { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Title = "Open a GBA/NDS File"; + ofd.Filter = "GBA/NDS/3DS file(*.gba;*.nds;*.3ds)|*.gba;*.nds;*.3ds"; + if (ofd.ShowDialog() == DialogResult.OK) { OpenROM(ofd.FileName); } + } + //public static Bits rom = new Bits(); + //public static Bits ram = new Bits(); + //Public OpenFileDialog1 = "" + public byte[] rom; + string romfn; + int version = -1; + int filetable = -1; + char language; + private void OpenROM(string filename) { //TODO: If new filename is error/incompatible, revert to old file. + //mainMem.setPath(filename) + //string vstr = ""; //Dim vstr As String = "" + if (filename.EndsWith(".nds", true, null)) + { + //Dark_Dawn a = new Dark_Dawn(); + new Dark_Dawn().init(filename); + } + else if (filename.EndsWith(".gba", true, null)) { //Load entire ROM to buffer; GBA ROMs are maxed at 32 MB. + rom = Bits.openFile(filename); + if (rom == null) { this.Text = "Error reading ROM file."; return; } + /* + HexEditor hx = new HexEditor(); + hx.init(); + hx.disp(); + */ + //rom.seek(0xA0); + //vstr = Bits.getString(rom, 0xA0, 16); + //ram.buffer = new byte[0x40000]; + switch (Bits.getString(rom, 0xA0, 15)) { + case "Golden_Sun_AAGS": //(U) GS1 + case "GOLDEN_SUN_AAGS": //Italy GS1 + case "OugonTaiyo_AAGS": //(J) GS1 + version = 0; filetable = 0x08320000; break; + case "GOLDEN_SUN_BAGF": + case "OUGONTAIYO_BAGF": + version = 1; filetable = 0x08680000; break; + case "MARIOTENNISABTM": + version = 11; filetable = 0x08C28000; break; + case "MARIOGOLFGBABMG": + version = 10; filetable = 0x08800000; break; + //default: + // MessageBox.Show("Not a compatible ROM."); + // break; + } + language = (char)rom[0xAF]; + if (language == 'E' && version == 1) { //Chinese check + if (Bits.getUInt32(rom, 0x08090000 & 0x01FFFFFF) == 0xEA00002E && //unchecked((int)0xEA00002E) && //Make UInt? + Bits.getUInt32(rom, 0x08090004 & 0x01FFFFFF) == 0x51AEFF24 && + Bits.getUInt32(rom, 0x08090008 & 0x01FFFFFF) == 0x21A29A69 && + Bits.getUInt32(rom, 0x0809000C & 0x01FFFFFF) == 0x0A82843D) { + language = 'C'; + } + } else if (version == 0) { + switch (language) { + case 'E': + case 'I': filetable = 0x08320000; break; + case 'J': filetable = 0x08317000; break; + case 'D': filetable = 0x0831FE00; break; + case 'F': + case 'S': filetable = 0x08321800; break; + } + } + //File table verification. + if (((Bits.getUInt32(rom, filetable & 0x01FFFFFF) >> 24) != 8) || + (Bits.getUInt32(rom, (filetable + 4) & 0x01FFFFFF) != filetable)) { + //Incompatible + } + //TODO: Reorganize repointed data from Atrius's editor back into where they should belong. + //Text data, filetable/map code data, Innate psys. + //count_freespace() + //init_globals + //with (obj_MasterEditor) { sel=6*(global.version>=10); event_user(0); } + loadEntireMap(); + //} else if (filename.EndsWith(".nds", true, null)) { //Dark Dawn? + } + romfn = filename; + Properties.Settings.Default.LastRom = filename; + Properties.Settings.Default.Save(); + if (palPath == null) + palPath = System.IO.Path.GetDirectoryName(Properties.Settings.Default.LastRom) + @"\palette.bin"; + } + string palPath; + //Toolbar > File menu + private void openToolStripMenuItem_Click(object sender, EventArgs e) { + OpenROMdialogue(); + } + private void saveToolStripMenuItem_Click(object sender, EventArgs e) { + Bits.saveFile(romfn, rom); + } + private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Title = "Save ROM File"; + //sfd.Filter = "GBA/NDS/3DS file(*.gba;*.nds;*.3ds)|*.gba;*.nds;*.3ds"; + if (sfd.ShowDialog() == DialogResult.OK) { + romfn = sfd.FileName; + Bits.saveFile(romfn, rom); + Properties.Settings.Default.LastRom = romfn; + Properties.Settings.Default.Save(); + } + } + private void nextMapToolStripMenuItem_Click(object sender, EventArgs e) { + if (sel == map_num) { return; } + sel += 1; + loadEntireMap(); + } + + private void previousMapToolStripMenuItem_Click(object sender, EventArgs e) { + if (sel == 0) { return; } + sel -= 1; + loadEntireMap(); + } + private void Form1_KeyDown(object sender, KeyEventArgs e) { + //MessageBox.Show(e.KeyData.ToString()); + switch (e.KeyCode) { + case (Keys)0x20: + tileDisp += 1; + if (tileDisp > 4) { tileDisp = 0; } + tWin(lastPressedKey, 1); + break; + case (Keys)0x21: + //if (sel == map_num) {return; } + //sel += 1; + int sel2 = (int)sel + 1; + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + sel2 = (int)sel + 10; + sel2 = Math.Min(sel2, map_num); + if (sel2 == sel) + return; + sel = (uint)sel2; + loadEntireMap(); + tWin(lastPressedKey, 0); + pictureBox1.Image.Save(romfn + ".png"); + break; + case (Keys)0x22: + //if (sel == 0) { return; } + //sel -= 1; + sel2 = (int)sel - 1; + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + sel2 = (int)sel - 10; + sel2 = Math.Max(sel2, 0); + if (sel2 == sel) + return; + sel = (uint)sel2; + loadEntireMap(); + tWin(lastPressedKey, 0); + break; + case (Keys)0x31: + if ((lastPressedKey == 0x31)) + { + hideLayer ^= 1 << (0x31 - 0x31); + //dispMap(); + } + tWin(0x31, 1); + //if (showhmap != 0) + dispMap(); + break; + case (Keys)0x32: + if ((lastPressedKey == 0x32)) + { + hideLayer ^= 1 << (0x32 - 0x31); + //dispMap(); + } + tWin(0x32, 1); + //if (showhmap != 0) + dispMap(); + break; + case (Keys)0x33: + if ((lastPressedKey == 0x33)) + { + hideLayer ^= 1 << (0x33 - 0x31); + //dispMap(); + } + //loadEntireMap(); + tWin(0x33, 1); + //if (showhmap != 0) + dispMap(); + break; + //default: + // Map.mapNum += 10; + // break; + case (Keys)0x48: //'h'=heightmap + showhmap ^= 1; + //if (showhmap > 2) + // showhmap = 0; + dispMap(); + break; + case (Keys)0x46: //'f'=Flatten/Unflatten + showhmap ^= 2; + dispMap(); + break; + case (Keys)0x47: //'g'=Cursor's y-based flattening. + showhmap ^= 4; + dispMap(); + break; + case (Keys)0x57: //'W'=For resize how many tiles display per row based on selection box's width.s + wr ^= 1; + tWin(lastPressedKey, 0); + break; + case (Keys)0x4C: //"L"=Layered or side-by-side + nlmap ^= 1; + loadEntireMap(); //Only to update scnw & scnh for now. + break; + case (Keys)0xC0: //'`' Oemtilde = Grid + if((Control.ModifierKeys & Keys.Control) != 0) + grid ^= 3; + else if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + grid ^= 2; + else + grid ^= 1; + dispMap(); + break; + case Keys.OemOpenBrackets: // [ + if (tilePal > 0) + tilePal -= 0x10; + tWin(lastPressedKey, 0); //dispMap(); + break; + case Keys.Oem6: //] + if (tilePal < 0xD0) + tilePal += 0x10; + tWin(lastPressedKey, 0); //dispMap(); + break; + + case Keys.E: //Export + //MessageBox.Show(Properties.Settings.Default.LastRom +" " + System.IO.Path.GetDirectoryName(Properties.Settings.Default.LastRom)); + //string path = System.IO.Path.GetDirectoryName(Properties.Settings.Default.LastRom) + @"\palette.bin"; + //MessageBox.Show(path); + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Title = "Save palette file"; + //ofd.Filter = "GBA/NDS/3DS file(*.gba;*.nds;*.3ds)|*.gba;*.nds;*.3ds"; + if (sfd.ShowDialog() == DialogResult.OK) { palPath = sfd.FileName; } else { break; } + } + //openFile(path); + //((PictureBox)ts.Controls[0]).Image.Save();///bmp/gif/jpg/png/tif + switch (palPath.Substring(palPath.Length - 4)) + { + case ".bmp": + case ".png": + case ".gif": + case ".jpg": + case ".tif": + ((PictureBox)ts.Controls[0]).Image.Save(palPath); + break; + default: + Bits.saveFile(palPath, paldat); + break; + } + //if ((new string[] { ".bmp", ".png", ".gif", ".jpg", ".tif" }).Contains(path.EndsWith()) { } + break; + case Keys.D: //Import + //palPath = System.IO.Path.GetDirectoryName(Properties.Settings.Default.LastRom) + @"\palette.bin"; + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Title = "Load palette file"; + //ofd.Filter = "GBA/NDS/3DS file(*.gba;*.nds;*.3ds)|*.gba;*.nds;*.3ds"; + if (ofd.ShowDialog() == DialogResult.OK) { palPath = ofd.FileName; } else { break; } + } + + switch (palPath.Substring(palPath.Length - 4)) + { + case ".bmp": + case ".png": + case ".gif": + case ".jpg": + case ".tif": + Bitmap palbmp = new Bitmap(palPath); + int wi = palbmp.Width / 16; + int hi = palbmp.Height / 16; + for (int h = 0; h < 14; h++) + { + for (int w = 0; w < 16; w++) + { + int pix = palbmp.GetPixel(w * wi, h * hi).ToArgb(); + paldat[h * 0x20 + w * 2] = (byte)(((pix >> 6) & 0xE0) | ((pix >> 19) & 0x1F)); + paldat[h * 0x20 + w * 2 + 1] = (byte)(((pix >> 1) & 0x7C) | ((pix >> 14) & 0x03)); + } + } + break; + default: + paldat = Bits.openFile(palPath); + break; + } + + //Compress + byte[] temp = new byte[0x10000]; + temp[0] = 1; //Compression Type 01 + int size = Comp.compressFormat1(paldat, 0, temp, 1)[1]; + size = (size + 3) & ~3; + Array.Resize(ref temp, size); + insertMFTfile(palfind, temp); + + initPal(paldat, 0, 0xE0); + tWin(lastPressedKey, 0); + dispMap(); //loadEntireMap(); + break; + } + } + int grid = 0; + int map_num = 0; + uint sel = 5;//202;//5;// 174; //5;// 44;//10;//4;//102;//5; + + static void genPixPosTabel(int bitmapWidth) { + int p = 0; + //for (int h = 0; h < 4; h += 1) { + for (short i = 0; i < 8 * bitmapWidth; i += (short)bitmapWidth) {//No flip table + for (short j = i; j < i + 8; j++) { + pixPosTable[p++] = j; + } + } + for (short i = 0; i < 8 * bitmapWidth; i += (short)bitmapWidth) { //X-flip table + for (short j = (short)(i + 7); i <= j; j--) { + pixPosTable[p++] = j; + } + } + for (short i = (short)(7 * bitmapWidth); 0 <= i; i -= (short)bitmapWidth) { //Y-flip table + for (short j = i; j < i + 8; j++) { + pixPosTable[p++] = j; + } + } + for (short i = (short)(7 * bitmapWidth); 0 <= i; i -= (short)bitmapWidth) { //X/Y-flip table + for (short j = (short)(i + 7); i <= j; j--) { + pixPosTable[p++] = j; + } + } + } + static short[] pixPosTable = new short[0x100]; //Maybe most useful for 3DS pixel rendering? (@GBA/DS unnested tiles: Doesn't really have a noticable speed increase?) + static byte[] blendflag = null;//Test. + static int bldmod = 0x3F4F;//0x3F42;//0x3C42; + static int eva = 8;//0x3C42; + static int evb = 0x10;//0x3C42; + byte[] paldat; byte[] tsetdat; byte[] stiles; byte[] tmap; byte[] hmap; byte[] visfx; + byte[] htiles; + int[] pos = new int[6]; + int scnw, scnh; + int mapfind; + int palfind; + int world_map; + void loadEntireMap() { + //init_globals + filetable &= 0x1FFFFFF; + uint maps_pos1 = Bits.getUInt32(rom, filetable + 0x18) & 0x1FFFFFF; + maps_pos1 = Bits.getUInt32(rom, unchecked((int)(maps_pos1 + 0xC))) & 0x1FFFFFF; + maps_pos1 = Bits.getUInt32(rom, unchecked((int)((maps_pos1 & 0x1FFFFFC) - 4 - 0x3C * ((version == 11) ? 1 : 0)))) & 0x1FFFFFF; + + //ds_map_add(global.data_desc,global.maps_pos1,"Map Data Reference 1") + uint maps_pos2 = Bits.getUInt32(rom, filetable + 0xC) & 0x1FFFFFF; + maps_pos2 = Bits.getUInt32(rom, unchecked((int)(maps_pos2 + 0x10C + 0x20 * ((version == 0) ? 1 : 0)))) & 0x1FFFFFF; + uint maps_off = Bits.getUInt32(rom, unchecked((int)((maps_pos2 & 0x1FFFFFC) - 4 - 0x160 * ((version == 0) ? 1 : 0)))) & 0x1FFFFFF; + maps_pos2 = Bits.getUInt32(rom, unchecked((int)((maps_pos2 & 0x1FFFFFC) - 8 - 0x164 * ((version == 0) ? 1 : 0)))) & 0x1FFFFFF; + + //ds_map_add(global.data_desc,global.maps_pos2,"Map Data Reference 2") + int mapid_str = 0; + + if (version == 0) { + switch (language) { + case 'J': mapid_str = 2624; break; + case 'E': mapid_str = 2567; break; + default: mapid_str = -1; break; + } + map_num = 201; + } else if (version == 1) { + switch (language) { + case 'J': mapid_str = 3772; break; + case 'D': + case 'S': + case 'F': + case 'I': mapid_str = 4231; break; + case 'E': + case 'C': mapid_str = 3770; break; + default: mapid_str = -1; break; + } + map_num = 325; + } else if (version == 10) { + mapid_str = 0; + map_num = 55; + } else if (version == 11) { + mapid_str = 882; + map_num = 69; + } + + //byte[] mapc = new byte[0x8000]; + //for (int a = 0x649; a < 0x6BB; a++) { + // decompress(rom, Bits.getInt32(rom, filetable + a * 4) & 0x1FFFFFF, mapc, 0); + // uint val = (uint)Bits.getInt32(mapc, 0); + // int i = 4; int j = 0; + // while (true) { + // if ((i & 3) == 0) { //POINTERS + // if ((val) == 0x03001238) { + // //val2 = (int)val & 0x1FFFFFE; + // MessageBox.Show(j.ToString("X8") + " | " + a.ToString("X8") + " --- " + i.ToString("X8") + ":" + val.ToString("X8")); j++; + // } + // } + // if (i >= mapc.Length) { break; } + // val = (val >> 8) | ((uint)mapc[i++] << 24); + // } + //} + + //obj_eMaps > User Defined 1 //Swap all to Unsigned? + //uint sel = 16; + uint loc = (maps_pos1 + 8 * sel) & 0x1FFFFFF; //file_bin_seek(global.file,(global.maps_pos1+8*sel)&$1FFFFFF) + int code = Bits.getInt16(rom, loc); //show_message(string_hex(READU8(global.file,READU32(global.file,(global.filetable+(code<<2)))),2)+', '+string_hex(dataresource_size(code),8)) + //rom(loc + 2) //Music/Name? + //rom(loc + 3) //??? + if (version == 10) //Golf + { + //@3= See table at 080686C0 in (U) version. ([+0xC]=Tilemap) + //@4= Likely uses a separate table as well. + if ((rom[loc + 3] == 3) || (rom[loc + 3] == 4)) + { + dMap = 0; // Don't display map. + this.Text = sel.ToString() + " - Type " + rom[loc + 3] + " is not currently supported."; // + " - " + pos[0].ToString("X8"); + return; + } + } + else if (version == 11) //Tennis + { + dMap = 0; // Don't display map. + this.Text = sel.ToString() + " - No maps supported until I fix it."; + return; + } + int map = Bits.getInt16(rom, loc + 4); + loc = unchecked((uint)((maps_pos2 + 12 * map) & 0x1FFFFFF)); //file_bin_seek(global.file,(global.maps_pos2+12*map)&$1FFFFFF) + pos[0] = Bits.getInt16(rom, loc); mapfind = pos[0] + (int)maps_off; + pos[1] = Bits.getInt16(rom, loc + 2); palfind = pos[1] + (int)maps_off; + pos[2] = Bits.getInt16(rom, loc + 4); + pos[3] = Bits.getInt16(rom, loc + 6); + pos[4] = Bits.getInt16(rom, loc + 8); + pos[5] = Bits.getInt16(rom, loc + 10); + + for (int a = 0; a < 6; a++) { + pos[a] = Bits.getInt32(rom, unchecked((int)(filetable + ((pos[a] + maps_off) << 2)) & 0x1FFFFFF)) & 0x1FFFFFF; + } + world_map = (map == 1) ? 1 : 0; + if (world_map == 1) { + if (version == 0) { + dispWMGS1(); return; + } else if (version == 1) { + dispWMGS2(); return; + } + } + /* Skip for now. + file_bin_seek(global.file,(global.filetable+(code<<2))&$1FFFFFF) + code=READ_UINT(global.file) + code_f=decompressMapCode(global.file,code,temp_directory+'\code.bin') + code=file_bin_open(code_f,2) + */ + //byte[] t = decompress(rom, 0xA8B1B8, 0); //Format 2 + //byte[] t = decompress(rom, 0x888FE4 + 0x80, 0); //Format 2 + //byte[] t = decompress16(rom, 0x4F157, 0); //Format 2 + //byte[] t = decompText(rom, 0x111); // decompBtlBG(rom, 0x7765D8 + 0x100); + paldat = new byte[0x1C0]; //0x200]; + Comp.decompress(rom, pos[1], paldat, 0); initPal(paldat, 0, 0xE0); //pictureBox1.Image = PixelsToImage(pal, 16, 14, 16); + tsetdat = new byte[0x10000]; + Comp.decompress(rom, pos[2], tsetdat, 0x0000); + Comp.decompress(rom, pos[3], tsetdat, 0x4000); + Comp.decompress(rom, pos[4], tsetdat, 0x8000); + Comp.decompress(rom, pos[5], tsetdat, 0xC000); + + scnw = rom[pos[0] + 0x2] * 8; + scnh = rom[pos[0] + 0x3] * 8; + + stiles = new byte[0x10000]; tmap = new byte[0x10000]; visfx = new byte[0x200]; + htiles = new byte[0x1000]; hmap = new byte[0x4000]; + //int length = + decompTileData(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x24)), stiles, 0); //8x8 tile table - Decompress & Deobfuscate. + Comp.decompress(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x28)), htiles, 0); //Height Tile Data - Skip for now. + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/htiles.dmp", htiles); + decompMap2(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x2C)), tmap, 0); //16x16 tilemap - Decompress & Deobfuscate. + + if (version == 1) { + Comp.decompress(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x30)), hmap, 0); //Height Tilemap + //Animation + if (Bits.getInt32(rom, pos[0] + 0x38) != 0) { Comp.decompress(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x38)), visfx, 0); } //catch { } //Visual Effects + } + //Coord data + + //shift[0]=READ_UBYTE(global.file)+(READ_UBYTE(global.file)<<7) + this.Text = sel.ToString() + " - " + pos[0].ToString("X8") + "-" + (Bits.getInt32(rom, unchecked((int)(filetable + ((mapfind + 1) << 2)) & 0x1FFFFFF)) & 0x1FFFFFF).ToString("X8"); + //Temporary error avoidance: + dMap = 0; + if (scnw == 0) { this.Text += (" (Error - Width was 0)").ToString(); scnw = 0x80 * 16; scnh = 0x36 * 16; } //Anti-error for... was it sel 102(?) + if (scnh == 0) { this.Text += (" (Error - Height was 0)").ToString(); scnh = 16; } + //if ((sel == 175) || (sel == 176) || (sel == 202) || (sel == 229)) { this.Text += (" (Error for 175, 176, 202, and 229)").ToString(); return; } + dMap = 1; + dispMap(); + //if (sel == 124) + //{ + // MessageBox.Show(Bits.getInt32(stiles, 0x1A0).ToString("X8") + " " + Bits.getInt32(stiles, 0x1A4).ToString("X8")); + //} + //if (sel == 125) + //{ + // MessageBox.Show(Bits.getInt32(stiles, 0x838).ToString("X8") + " " + Bits.getInt32(stiles, 0x83C).ToString("X8")); + //} + } + void dispWMGS1() { + paldat = new byte[0x800]; tsetdat = new byte[0x20000]; + int wmflst = 0x132CC;// +(9 * 4 * 3); + pal = new int[0x400]; + for (int j = 0; j < 2; j++) { + int i = j * 0x8000; + Comp.decompressf(rom, Bits.getInt32(rom, 0x320000 + 4 * Bits.getInt32(rom, wmflst)) & 0x1FFFFFF, paldat, j * 0x200, 1); + //Comp.decompress(rom, 0x680000 + 4 * Bits.getInt32(rom, 0x2ED34 + 4), , 0); //Animation Data (Ignore) + //Comp.decompress(rom, 0x680000 + 4 * Bits.getInt32(rom, 0x2ED34 + 8), , 0); //Terrain Tileset (Ignore) + Comp.decompress(rom, Bits.getInt32(rom, 0x320000 + 4 * Bits.getInt32(rom, wmflst + 0x4)) & 0x1FFFFFF, tsetdat, i + 0x0000); //Tileset 1 + Comp.decompress(rom, Bits.getInt32(rom, 0x320000 + 4 * Bits.getInt32(rom, wmflst + 0x8)) & 0x1FFFFFF, tsetdat, i + 0x2000); //Tileset 2 + Comp.decompress(rom, Bits.getInt32(rom, 0x320000 + 4 * Bits.getInt32(rom, wmflst + 0xC)) & 0x1FFFFFF, tsetdat, i + 0x4000); //Tileset 3 + Comp.decompress(rom, Bits.getInt32(rom, 0x320000 + 4 * Bits.getInt32(rom, wmflst + 0x10)) & 0x1FFFFFF, tsetdat, i + 0x6000); //Tileset 4 + + //Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x1C)) & 0x1FFFFFF, tsetdat, 0x8000); //Animated Tileset 1 + //Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x20)) & 0x1FFFFFF, tsetdat, 0xA000); //Animated Tileset 2 + wmflst += 0x18; + } + initPal(paldat, 0, 0x400); + stiles = new byte[0x10000]; + Comp.decompress(rom, Bits.getInt32(rom, 0x320000 + 4 * 0xD5) & 0x1FFFFFF, stiles, 0x0000); //8x8 tiles + + //Comp.decompress(rom, 0x680000 + 4 * 0x199, , 0x0000); //Misc data (0x0202E000) + + scnw = 0x1000; scnh = 0x1400; + //int[] bmpdata = new int[scnw * scnh]; + + int wmpos = Bits.getInt32(rom, 0x320000 + 4 * 0xD4) & 0x1FFFFFF; + //byte[] mapdata = new byte[0x400]; + byte[] mapdata = new byte[0x800]; + int iOffset = 0; + int tspos = 0; int highind = 0; + int[] bmpdata = new int[scnw * scnh]; + while (iOffset < 0x500) { + for (int yMap = 0; yMap < scnh; yMap += 0x100) { + for (int xMap = 0; xMap < scnw; xMap += 0x100) { + int rptr = Bits.getInt32(rom, wmpos + iOffset); //iOffset += 4; + int rptr2 = Bits.getInt32(rom, wmpos + iOffset + 0x500); iOffset += 4; + if (rptr == 0) { continue; } + Comp.decompressf(rom, wmpos + rptr, mapdata, 0x0000, 1); //Map data + //int t = 0; + if (rptr2 == 0) { continue; } + Comp.decompressf(rom, wmpos + rptr2, mapdata, 0x0400, 1); + int iOffset2 = 0; + while (iOffset2 < 0x800) + { + for (int row = yMap; row < yMap + 0x100; row += 16) + { + for (int col = xMap; col < xMap + 0x100; col += 16) + { + int t = Bits.getInt16(mapdata, iOffset2) * 4; + int tsNum = mapdata[(iOffset2 & 0x3FF) + 3] & 0x7F; + //if (tsNum > highind) { highind = tsNum; } + //if ((tsNum > 0) && (iOffset > 0x500)) { MessageBox.Show("Hahaha!"); } + if (tsNum == 0x15) + { + tsNum = 1; + } + else { tsNum = 0; } + iOffset2 += 4; + for (int r = row; r < row + 16; r += 8) + { + for (int c = col; c < col + 16; c += 8) + { + int tile = stiles[t++];// tspos++; + int pos = tsNum * 0x8000 + (tile << 6); + if (iOffset2 > 0x400) { pos += 0x4000; } // > is intentional do to +4 above. + for (int y = r; y <= r + 7; y++) + { + for (int x = c; x <= c + 7; x++) + { + if (tsetdat[pos] == 0) { pos++; continue; } + bmpdata[(y * scnw) + x] = pal[tsNum * 0x100 + tsetdat[pos++]]; + } + } + } + } + //tsNum = mapdata[iOffset2 - 4 + 2];// &0x7F; + //for (int r = row; r < row + 16; r += 8) + //{ + // for (int c = col; c < col + 16; c += 8) + // { + // //int tile = stiles[t++];// tspos++; + // //int pos = tsNum * 0x8000 + (tile << 6); + // if (tsNum == 0) { continue; } + // if (iOffset2 > 0x400) { continue; } // pos += 0x4000; } // > is intentional do to +4 above. + // for (int y = r; y <= r + 7; y++) + // { + // for (int x = c; x <= c + 7; x++) + // { + // //if (tsetdat[pos] == 0) { pos++; continue; } + // if ((tsNum & 1) == 1) { bmpdata[(y * scnw) + x] = 0xC0C0C0; } else { bmpdata[(y * scnw) + x] = 0x404040; } // pal[0]; + // } + // tsNum >>= 1; + // } + // } + //} + } + } + } + } + } + } + //MessageBox.Show(highind.ToString("X4")); + //for (int r = 0; r < 0x180; r += 8) { + // for (int c = 0; c < 0x80; c += 8) { + // int tile = tspos++; + // int pos = tile << 6; + // for (int y = r; y <= r + 7; y++) { + // for (int x = c; x <= c + 7; x++) { + // bmpdata[(y * scnw) + x] = pal[tsetdat[pos++]]; + // } + // } + // } + //} + pictureBox1.Width = scnw; pictureBox1.Height = scnh; + pictureBox1.Image = PixelsToImage(bmpdata, scnw, scnh); + //pictureBox1.Image.Save(@"C:\Users\Tea\Desktop\GS1WorldMap.png"); + } + void dispWMGS2() { + paldat = new byte[0x800]; tsetdat = new byte[0x20000]; + int wmflst = 0x2ED34;// +(9 * 4 * 3); + pal = new int[0x400]; + for (int j = 0; j < 4; j++) { + int i = j * 0x8000; + Comp.decompressf(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst)) & 0x1FFFFFF, paldat, j * 0x200, 1); + //Comp.decompress(rom, 0x680000 + 4 * Bits.getInt32(rom, 0x2ED34 + 4), , 0); //Animation Data (Ignore) + //Comp.decompress(rom, 0x680000 + 4 * Bits.getInt32(rom, 0x2ED34 + 8), , 0); //Terrain Tileset (Ignore) + Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0xC)) & 0x1FFFFFF, tsetdat, i + 0x0000); //Tileset 1 + Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x10)) & 0x1FFFFFF, tsetdat, i + 0x2000); //Tileset 2 + Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x14)) & 0x1FFFFFF, tsetdat, i + 0x4000); //Tileset 3 + Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x18)) & 0x1FFFFFF, tsetdat, i + 0x6000); //Tileset 4 + + //Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x1C)) & 0x1FFFFFF, tsetdat, 0x8000); //Animated Tileset 1 + //Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * Bits.getInt32(rom, wmflst + 0x20)) & 0x1FFFFFF, tsetdat, 0xA000); //Animated Tileset 2 + wmflst += 0x24; + } + initPal(paldat, 0, 0x400); + stiles = new byte[0x10000]; + Comp.decompress(rom, Bits.getInt32(rom, 0x680000 + 4 * 0x198) & 0x1FFFFFF, stiles, 0x0000); //8x8 tiles + + //Comp.decompress(rom, 0x680000 + 4 * 0x199, , 0x0000); //Misc data (0x0202E000) + + scnw = 0x2000; scnh = 0x2000; + //int[] bmpdata = new int[scnw * scnh]; + + int wmpos = Bits.getInt32(rom, 0x680000 + 4 * 0x197) & 0x1FFFFFF; + //byte[] mapdata = new byte[0x400]; + byte[] mapdata = new byte[0x800]; + int iOffset = 0; + int tspos = 0; + int[] bmpdata = new int[scnw * scnh]; + while (iOffset < 0x1000) { + for (int yMap = 0; yMap < scnh; yMap += 0x100) { + for (int xMap = 0; xMap < scnw; xMap += 0x100) { + int rptr = Bits.getInt32(rom, wmpos + iOffset); //iOffset += 4; + int rptr2 = Bits.getInt32(rom, wmpos + 0x1000 + iOffset); iOffset += 4; + //if (rptr == 0) { continue; } + //Comp.decompressf(rom, wmpos + rptr, mapdata, 0x0000, 1); //Map data + //if (rptr2 == 0) { continue; } + //Comp.decompressf(rom, wmpos + rptr2, mapdata, 0x0400, 1); //WIP + int iOffset2 = 0; + while (iOffset2 < 0x800) + { + if (iOffset2 < 0x400) + { + if (rptr == 0) { iOffset2 = 0x400; continue; } + Comp.decompressf(rom, wmpos + rptr, mapdata, 0x0000, 1); //Map data + } + else + { + if (rptr2 == 0) { iOffset2 = 0x800; continue; } + Comp.decompressf(rom, wmpos + rptr2, mapdata, 0x0400, 1); //WIP + } + for (int row = yMap; row < yMap + 0x100; row += 16) + { + for (int col = xMap; col < xMap + 0x100; col += 16) + { + int t = Bits.getInt16(mapdata, iOffset2) * 4; + int tsNum = mapdata[(iOffset2 & 0x3FF) + 3] & 0x3F; + if (tsNum < 0x14) + { + tsNum = 0; + } + else if (tsNum < 0x1E) + { + tsNum = 2; + } + else if (tsNum < 0x28) + { + tsNum = 3; + } + else if (tsNum < 0x32) + { + tsNum = 1; + } + else { tsNum = 0; } + iOffset2 += 4; + //stiles[t] + for (int r = row; r < row + 16; r += 8) + { + for (int c = col; c < col + 16; c += 8) + { + int tile = stiles[t++];// tspos++; + int pos = tsNum * 0x8000 + (tile << 6); + if (iOffset2 > 0x400) { pos += 0x4000; } + for (int y = r; y <= r + 7; y++) + { + for (int x = c; x <= c + 7; x++) + { + if (tsetdat[pos] == 0) { pos++; continue; } + bmpdata[(y * scnw) + x] = pal[tsNum * 0x100 + tsetdat[pos++]]; + } + } + } + } + } + } + } + } + } + } + //for (int r = 0; r < 0x180; r += 8) { + // for (int c = 0; c < 0x80; c += 8) { + // int tile = tspos++; + // int pos = tile << 6; + // for (int y = r; y <= r + 7; y++) { + // for (int x = c; x <= c + 7; x++) { + // bmpdata[(y * scnw) + x] = pal[tsetdat[pos++]]; + // } + // } + // } + //} + pictureBox1.Width = scnw; pictureBox1.Height = scnh; + pictureBox1.Image = PixelsToImage(bmpdata, scnw, scnh); + } + int dMap = 1; + int showhmap = 0; + int[] bmpdata = new int[1]; + int nlmap = 0; //nl = no layer / as in just 1 layer of everything. + void dispMap() { + if (dMap == 0) { return; } + if (world_map == 1) + { + if (version == 0) + { + dispWMGS1(); return; + } + else if (version == 1) + { + dispWMGS2(); return; + } + } + //if ((showhmap & 1) != 0) + //{ + // pictureBox1.Width = scnw; pictureBox1.Height = scnh; + // pictureBox1.Image = disphmap(); + // //pictureBox1.Image = dispPrioMap();// + // return; + //} + //if (bmpdata.Length != scnw * scnh) + if (nlmap == 1) + { + scnw = 0x800; + scnh = 0x800; + } + bmpdata = new int[scnw * scnh]; + //for (int l = 0; l < 3; l += 1) { + // int shift = rom[pos[0] + 0xC + (l * 8)] + (rom[pos[0] + 0xD + (l * 8)] << 7); + // for (int dy = 0; dy < rom[pos[0] + 0x3]; dy += 2) { + // for (int dx = 0; dx < rom[pos[0] + 0x2]; dx += 2) { + // int t = Bits.getInt16(tmap, 0x8000 + dx + shift + (dy << 7)) & 0xFFF; + // for (int t8 = 0; t8 < 8; t8 += 2) { + // int tile = Bits.getInt16(stiles, t * 8); + // int t2 = ((tile & 0x3FF) + ((rom[pos[0] + 7 + l] - 1) * 0x200)) << 5; //+ tset + // int tilePal = (tile >> 8) & 0xF0; + // for (int n = 0; n < 0x40; n += 2) { + // int ry = y; if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + // int rx = x; if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + // int pix = tsetdat[t2++]; + // int pix2 = pix & 0xF; + // if (pix2 != 0) { + // bmpdata[((dy*8 + (t8&4)*2 + (n>>3)) * width) + rx] = pal[tilePal | (pix2)]; + // } + // int rx = x + 1; if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + // pix2 = pix >> 4; + // if (pix2 != 0) { + // bmpdata[(ry * width) + rx] = pal[tilePal | (pix2)]; + // } + // } + // } + // } + // } + //} + //int mappos = 0; + //return; + //try { + genPixPosTabel(scnw); + //PREPARE BLENDING INFO! + blendflag = new byte[(scnw * scnh) >> 3];// bldmod = 0; + bldmod = Bits.getInt16(visfx, 0);// | 0xF; + eva = visfx[2]; + evb = visfx[3]; + //int bldaddr = 0x3B78AC + (rom[0x3A78D4 + (mapNum * 0x18) + 0x9] << 3); + //bldmod = Bits.getInt32(rom, bldaddr); + //bldmod = ((bldmod & 0xFC0) << 2) | (bldmod & 0x3F); + //int evaddr = Bits.getInt32(rom, bldaddr + 4); + //if (evaddr != 0) { + // bldmod |= 0x40; + // int evdata = Bits.getInt32(rom, evaddr & 0x1FFFFFF); + // eva = evdata & 0x1F; + // evb = (evdata >> 5) & 0x1F; + //} + //Text += " " +hideLayer.ToString(); + int m = 0; int l = 3; + int layiOffset = 1; + int shiftx = 0, shifty = 0; + int shift = 0; + while (m < 4) { //for (int m = 1; m <= 3; m++) { + if (nlmap != 0) //Quick hack + { + m = 4; + l = lastPressedKey - 0x31; + l &= 3; if (l == 3) { l = 0; } + goto jmp1; + } + l--; //int l = 2; + while ((l >= 0) && (rom[pos[0] + 4 + l] != m)) { + l--; + } + if (l < 0) { l = 3; m++; continue; } + layiOffset = 1 << (3 - l); + shiftx = rom[pos[0] + 0xC + (l * 8)]; shifty = rom[pos[0] + 0xD + (l * 8)]; + shift = (shiftx & 0xfe) + ((shifty & 0xfe) << 7); + if ((hideLayer & (1 << l)) != 0) + continue; + jmp1: + for (int row = 0; row < (scnh); row += 16) { + for (int col = 0; col < (scnw); col += 16) { + //int t = Bits.getInt16(tmap, 0x8000 + dx + shift + (dy << 7)) & 0xFFF; + //Quick fix for when some layers are likely smaller than the map area? (e.g. slower scrolling) + //This is only needed for a few maps. (At least 2? 175/176) + if ((0x8000 + (col >> 3) + shift + (row << 4)) >= 0x10000) + break; + int t = (Bits.getInt16(tmap, 0x8000 + (col >> 3) + shift + (row << 4)) & 0xFFF) * 8; + //try { + for (int r = row; r < row + 16; r += 8) { + //Quick fix for when the map height is an odd number. + if (r >= scnh) + break; + for (int c = col; c < col + 16; c += 8) { + //Quick fix for when the map width is an odd number. + if (c >= scnw) + break; + + int tile = Bits.getInt16(stiles, t); t += 2; + + int q = (tile >> 4) & 0xC0; + int tilepos = ((r * scnw) + c); + //int k = q + 0x40; + //int t2 = ((tile & 0x3FF) + ((rom[pos[0] + 7 + l] - 1) * 0x200)) << 5; //+ tset + int t2 = ((tile & 0x3FF) << 5) + ((rom[pos[0] + 7 + l] - 1) * 0x4000); //+ tset + if (t2 >= 0) { + int tilePal = (tile >> 8) & 0xF0; + for (int y = r; y <= r + 7; y++) { + int ry = y; if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + ry -= (shifty & 1) * 8; if (ry < 0) { continue; } + //int pix = ram.getInt32(pos); pos += 4; + for (int x = c; x <= c + 7; x += 2) { + int rx = x; if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + rx -= (shiftx & 1) * 8; if (rx < 0) { continue; } + int pix = tsetdat[t2++]; + int pix2 = pix & 0xF; + if (pix2 != 0) { + //bmpdata[(ry * scnw) + rx] = pal[tilePal | (pix2)]; + //priomap[(ry * bitmapWidth) + rx] = priority; + int mappos = tilepos + pixPosTable[q]; + if (((blendflag[mappos >> 3] >> (mappos & 7)) & 1) == 1) { + if ((bldmod & (0xC0 | (layiOffset << 8))) == (0x40 | (layiOffset << 8))) { + bmpdata[mappos] = blendit(bmpdata[mappos], pal[tilePal | pix2], eva, evb); + } + blendflag[mappos >> 3] ^= (byte)(1 << (mappos & 7)); + } else if (bmpdata[mappos] == 0) { + bmpdata[mappos] = pal[tilePal | pix2]; + //priomap[(ry * bitmapWidth) + rx] = priority; + if ((bldmod & (0xC0 | layiOffset)) == (0x40 | layiOffset)) { + blendflag[mappos >> 3] |= (byte)(1 << (mappos & 7)); + } + } + } q++; + //pix >>= 4; + rx = x + 1; if ((tile & 0x400) != 0) { rx = c + ((7 - (x + 1)) & 7); } //Horr. flip + pix2 = pix >> 4; + if (pix2 != 0) { + //bmpdata[(ry * scnw) + rx] = pal[tilePal | (pix2)]; + //priomap[(ry * bitmapWidth) + rx] = priority; + int mappos = tilepos + pixPosTable[q]; + if (((blendflag[mappos >> 3] >> (mappos & 7)) & 1) == 1) { + if ((bldmod & (0xC0 | (layiOffset << 8))) == (0x40 | (layiOffset << 8))) { + bmpdata[mappos] = blendit(bmpdata[mappos], pal[tilePal | pix2], eva, evb); + } + blendflag[mappos >> 3] ^= (byte)(1 << (mappos & 7)); + } else if (bmpdata[mappos] == 0) { + bmpdata[mappos] = pal[tilePal | pix2]; + //priomap[(ry * bitmapWidth) + rx] = priority; + if ((bldmod & (0xC0 | layiOffset)) == (0x40 | layiOffset)) { + blendflag[mappos >> 3] |= (byte)(1 << (mappos & 7)); + } + } + } q++; + //pix >>= 4; + } + } + } + } + } + //} catch { } + } + } + + } + //} catch { } + if ((grid & 1) != 0) + { + for (int row = 0; row < (scnh); row += 1) + { + for (int col = 0; col < (scnw); col += 1) + { + if (((col & 0xF) == 0xF) || ((row & 0xF) == 0xF)) + { + bmpdata[row * scnw + col] = 0; + } + } + } + } + if ((grid & 2) != 0) + { + for (int row = 0; row < (scnh); row += 1) + { + for (int col = 0; col < (scnw); col += 1) + { + if (((col & 0xF) == 0) || ((row & 0xF) == 0)) + //if ((((col & row) & 0xF) == 0)) //Nope... Random fun, though. + { + bmpdata[row * scnw + col] = 0; + } + } + } + } + if (tileDisp == 4) + { + dispPrioMap(); + } + else if ((showhmap & 1) != 0) + { + //Text += ">"; + disphmap(); + //Text += "<"; + + //pictureBox1.Width = scnw; pictureBox1.Height = scnh; + //pictureBox1.Image = disphmap(); + //pictureBox1.Image = dispPrioMap();// + //return; + } + + pictureBox1.Width = scnw; pictureBox1.Height = scnh; + pictureBox1.Image = PixelsToImage(bmpdata, scnw, scnh); + //System.IO.File.WriteAllBytes("C:/Users/Tea/Desktop/gsdtest.dmp", tsetdat); //stiles); + } + //void tile_add(int[] mapBmp, int mapPos, byte[] tsetBmp, int tsetPos, int[] pal, int tileInfo) { + + //} + public static int blendit(int first, int second, int eva, int evb) { + int blue = (((byte)first * eva) >> 4) + (((byte)second * evb) >> 4); + if (blue > 0xF8) { blue = 0xF8; } + int green = (((byte)(first >> 8) * eva) >> 4) + (((byte)(second >> 8) * evb) >> 4); + if (green > 0xF8) { green = 0xF8; } + int red = (((byte)(first >> 16) * eva) >> 4) + (((byte)(second >> 16) * evb) >> 4); + if (red > 0xF8) { red = 0xF8; } + return unchecked((int)0xFF000000) | ((red << 16) | (green << 8) | blue) & 0xF8F8F8; + } + public int[] pal = new int[0x100]; + public void initPal(byte[] src, int srcPos, int num) { // int[] des, int desPos, int num) { //Loads palette data into 32-bit array with reversed format. + //rom.seek(0x8C88C8); + for (int i = 0; i < num; i++) { + int palt = Bits.getInt16(src, srcPos + (i * 2)); + //pal[i] = (short)(((palt & 0x1F) << 10) | (palt & 0x3E0) | (palt >> 10)); + pal[i] = unchecked((int)0xFF000000) | ((palt & 0x1F) << 0x13) | ((palt & 0x3E0) << 6) | ((palt >> 7) & 0xF8); + } + } + //Only needed to display zoomed in Palette bitmap, + public static Bitmap PixelsToImage(int[] array, int width, int height, int zoom) { + if (zoom <= 0) { return new Bitmap(1, 1); } + int[] array2 = new int[width * height * zoom * zoom]; + //for (int i = 0; i < (width * height); i++) { + int i = 0; + for (int yt = 0; yt < (height * zoom) * (width * zoom); yt += (width * zoom) * zoom) { + for (int xt = yt; xt < yt + (width * zoom); xt += zoom) { + int palt = array[i++]; + for (int y = xt; y < xt + (width * zoom) * zoom; y += (width * zoom)) { + for (int x = y; x < y + zoom; x++) { + array2[x] = palt; + } + } + } + } + return PixelsToImage(array2, width * zoom, height * zoom); + } + public static Bitmap PixelsToImage(int[] array, int width, int height) { + Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); + Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); + BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat); + IntPtr pNative = bitmapData.Scan0; + Marshal.Copy(array, 0, pNative, width * height); + bitmap.UnlockBits(bitmapData); + return bitmap; + } + + void decompTileData(byte[] src, int srcPos, byte[] des, int desPos) { + byte[] t = new byte[0x10000]; + int length = Comp.decompress(src, srcPos, t, desPos)[1]; + //MessageBox.Show( ""+t[0]); + //byte[] stiles = new byte[0x8000]; + int i = 0, pos1, pos2, n = 0; + switch (t[0]) { + case 1: + pos2 = (length >> 1) + 1; + for (pos1 = 1; pos1 <= (length >> 1); i += 2) { + n ^= ((t[pos1++] << 8) | (t[pos2++])); + des[i] = (byte)n; des[i + 1] = (byte)(n >> 8); + } + break; + case 2: + for (i = 1; i < (length - 1); i += 2) { + n ^= t[i] | (t[i + 1] << 8); + des[i - 1] = (byte)n; des[i] = (byte)(n >> 8); + } + break; + default: //case 0: + for (i = 0; i < length; i++) { + des[i] = t[i + 1]; + } + break; + } + length--; + t8amt = length >> 3; + } + void decompMap2(byte[] src, int srcPos, byte[] des, int desPos) { + Comp.decompress(src, srcPos, des, desPos); + uint b = 0xFFFFF001, pos1, num; + for (pos1 = 0x8000; pos1 < 0x10000; pos1 += 2) { + num = (uint)(des[pos1] | (des[pos1 + 1] << 8)); + if ((num << 20) == 0xFFF00000) { + num += b; + if (b != 0) { b++; } + } + des[pos1] = (byte)num; des[pos1 + 1] = (byte)(num >> 8); + } + } + + private void editorsToolStripMenuItem_Click(object sender, EventArgs e) { + Editors eds = new Editors(); + eds.test = this; + eds.Show(); + } + //byte[] paldat; byte[] tsetdat; byte[] stiles; + int tilePal = 0; + public Bitmap dispTsetImg(int charBase) + { //, int tilePal) { + int tspos = 0; + int[] bmpdata = new int[0x80000]; + //for (int row = 0; row < 0x200; row += 16) { + //for (int col = 0; col < 0x100; col += 16) { + for (int r = 0; r < 0x280; r += 8) + { + for (int c = 0; c < 0x100; c += 8) + { + //int tile = rom.getInt16(tsetaddr[0] + tspos); tspos += 2; + int tile = tspos;//Bits.getInt16(stiles, tspos); + tspos += 1; + //if (tsetaddr[tspos >> 12] == -1) { tile = 0; } else { tile = Bits.getInt16(rom, tsetaddr[tspos >> 12] + (tspos & 0xFFF)); tspos += 2; } //tspos &= 0xFFF; + int pos = tile << 5; // (tile & 0x3FF) << 5; + //pos += charBase; + //int tilePal = 0;// (tile >> 8) & 0xF0; + pos -= 0x4000; if (pos < 0) { continue; } + //int x1, x2, xi, y1, y2, yi; // Not sure how I wanted flipping coded in? Alternative below, though! + //if ((tile & 0x400) == 0) { x1 = 0; x2 = 7; xi = 1; } else { x1 = 7; x2 = 0; xi = -1; }; + //if ((tile & 0x800) == 0) { y1 = 0; y2 = 7; yi = 1; } else { y1 = 7; y2 = 0; yi = -1; }; + for (int y = r; y <= r + 7; y++) + { + int ry = y; //if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + int pix = Bits.getInt32(tsetdat, pos); pos += 4; + for (int x = c; x <= c + 7; x++) + { + int rx = x; //if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + bmpdata[(ry << 9) + rx] = pal[tilePal | (pix & 0xF)]; + pix >>= 4; + } + } + } + } + //} + //} + //charBase indicator + for (int y = 0; y < charBase; y++) + { + bmpdata[(y << 9) + 0x100] = 0xF80000; + bmpdata[(y << 9) + 0x101] = 0xF80000; + } + for (int y = charBase; y < charBase + 0x100; y++) + { + bmpdata[(y << 9) + 0x100] = 0x00F800; + bmpdata[(y << 9) + 0x101] = 0x00F800; + } + for (int y = charBase + 0x100; y < 0x200; y++) + { + bmpdata[(y << 9) + 0x100] = 0xF80000; + bmpdata[(y << 9) + 0x101] = 0xF80000; + } + return PixelsToImage(bmpdata, 0x200, 0x400); + } + public Bitmap dispTsetImgWM(int charBase) + { //, int tilePal) { + int tspos = 0; + int[] bmpdata = new int[0x80000]; + //for (int row = 0; row < 0x200; row += 16) { + //for (int col = 0; col < 0x100; col += 16) { + for (int r = 0; r < 0x100; r += 8) + { + for (int c = 0; c < 0x80; c += 8) + { + //int tile = rom.getInt16(tsetaddr[0] + tspos); tspos += 2; + int tile = tspos;//Bits.getInt16(stiles, tspos); + tspos += 1; + //if (tsetaddr[tspos >> 12] == -1) { tile = 0; } else { tile = Bits.getInt16(rom, tsetaddr[tspos >> 12] + (tspos & 0xFFF)); tspos += 2; } //tspos &= 0xFFF; + int pos = tile << 6; // (tile & 0x3FF) << 5; + //pos += charBase; + //int tilePal = 0;// (tile >> 8) & 0xF0; + //pos -= 0x4000; + if (pos < 0) { continue; } + //int x1, x2, xi, y1, y2, yi; // Not sure how I wanted flipping coded in? Alternative below, though! + //if ((tile & 0x400) == 0) { x1 = 0; x2 = 7; xi = 1; } else { x1 = 7; x2 = 0; xi = -1; }; + //if ((tile & 0x800) == 0) { y1 = 0; y2 = 7; yi = 1; } else { y1 = 7; y2 = 0; yi = -1; }; + for (int y = r; y <= r + 7; y++) + { + int ry = y; //if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + //int pix = Bits.getInt32(tsetdat, pos); pos += 4; + for (int x = c; x <= c + 7; x++) + { + int rx = x; //if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + bmpdata[(ry << 9) + rx] = pal[tsetdat[pos++]]; + //pix >>= 4; + } + } + } + } + //} + //} + //charBase indicator + for (int y = 0; y < charBase; y++) + { + bmpdata[(y << 9) + 0x100] = 0xF80000; + bmpdata[(y << 9) + 0x101] = 0xF80000; + } + for (int y = charBase; y < charBase + 0x100; y++) + { + bmpdata[(y << 9) + 0x100] = 0x00F800; + bmpdata[(y << 9) + 0x101] = 0x00F800; + } + for (int y = charBase + 0x100; y < 0x200; y++) + { + bmpdata[(y << 9) + 0x100] = 0xF80000; + bmpdata[(y << 9) + 0x101] = 0xF80000; + } + return PixelsToImage(bmpdata, 0x200, 0x400); + } + int wr = 0; //width resize of tile table image.... (0 or 1) + public Bitmap dispTileset(int charBase) + {//(ByVal tsslot As Integer) { + + //tsetaddr[0] + //int maxWidth = (ts.Width & ~0xF) - 17; + int maxWidth = 0x200; + if (wr != 0) + maxWidth = (ts.Width - 33) & ~0xF; //0x200 + //int maxHeight = 0x8000 / (maxWidth>>4); + int tspos = 0; + //int[] bmpdata = new int[0x20000]; + int[] bmpdata = new int[0x80000]; + //for (int row = 0; row < 16; row++) { + // for (int col = 0; col < 32; col++) { + for (int row = 0; row < 0x400; row += 16) + { + for (int col = 0; col < maxWidth; col += 16) + { + for (int r = row; r < row + 16; r += 8) + { + for (int c = col; c < col + 16; c += 8) + { + //int tile = rom.getInt16(tsetaddr[0] + tspos); tspos += 2; + int tile = Bits.getInt16(stiles, tspos); tspos += 2; + //if (tsetaddr[tspos >> 12] == -1) { tile = 0; } else { tile = Bits.getInt16(rom, tsetaddr[tspos >> 12] + (tspos & 0xFFF)); tspos += 2; } //tspos &= 0xFFF; + int pos = (tile & 0x3FF) << 5; + pos += charBase; + int tilePal = (tile >> 8) & 0xF0; + pos -= 0x4000; if (pos < 0) { continue; } + //int x1, x2, xi, y1, y2, yi; // Not sure how I wanted flipping coded in? Alternative below, though! + //if ((tile & 0x400) == 0) { x1 = 0; x2 = 7; xi = 1; } else { x1 = 7; x2 = 0; xi = -1; }; + //if ((tile & 0x800) == 0) { y1 = 0; y2 = 7; yi = 1; } else { y1 = 7; y2 = 0; yi = -1; }; + for (int y = r; y <= r + 7; y++) + { + int ry = y; if ((tile & 0x800) != 0) { ry = r + ((7 - y) & 7); } //Vert. flip + int pix = Bits.getInt32(tsetdat, pos); pos += 4; + for (int x = c; x <= c + 7; x++) + { + int rx = x; if ((tile & 0x400) != 0) { rx = c + ((7 - x) & 7); } //Horr. flip + bmpdata[(ry << 9) + rx] = pal[tilePal | (pix & 0xF)]; + pix >>= 4; + } + } + } + } + } + } + return PixelsToImage(bmpdata, 0x200, 0x400);// 0x100); + } + public Bitmap dispTilesetWM(int charBase) + {//(ByVal tsslot As Integer) { + + //tsetaddr[0] + //int maxWidth = (ts.Width & ~0xF) - 17; + int maxWidth = 0x200; + if (wr != 0) + maxWidth = (ts.Width - 33) & ~0xF; //0x200 + //int maxHeight = 0x8000 / (maxWidth>>4); + int tspos = 0; + //int[] bmpdata = new int[0x20000]; + int[] bmpdata = new int[0x80000]; + //for (int row = 0; row < 16; row++) { + // for (int col = 0; col < 32; col++) { + for (int row = 0; row < 0x400; row += 16) + { + for (int col = 0; col < maxWidth; col += 16) + { + for (int r = row; r < row + 16; r += 8) + { + for (int c = col; c < col + 16; c += 8) + { + //int tile = rom.getInt16(tsetaddr[0] + tspos); tspos += 2; + //int tile = Bits.getInt16(stiles, tspos); tspos += 2; + int tile = stiles[tspos++]; + //if (tsetaddr[tspos >> 12] == -1) { tile = 0; } else { tile = Bits.getInt16(rom, tsetaddr[tspos >> 12] + (tspos & 0xFFF)); tspos += 2; } //tspos &= 0xFFF; + int pos = (tile & 0x3FF) << 6; + //pos += charBase; + //int tilePal = (tile >> 8) & 0xF0; + //pos -= 0x4000; + if (pos < 0) { continue; } + //int x1, x2, xi, y1, y2, yi; // Not sure how I wanted flipping coded in? Alternative below, though! + //if ((tile & 0x400) == 0) { x1 = 0; x2 = 7; xi = 1; } else { x1 = 7; x2 = 0; xi = -1; }; + //if ((tile & 0x800) == 0) { y1 = 0; y2 = 7; yi = 1; } else { y1 = 7; y2 = 0; yi = -1; }; + for (int y = r; y <= r + 7; y++) + { + int ry = y; if ((tile & 0x800) != 0) { ry ^= 7; } // r + ((7 - y) & 7); } //Vert. flip + //int pix = Bits.getInt32(tsetdat, pos); pos += 4; + for (int x = c; x <= c + 7; x++) + { + int rx = x; if ((tile & 0x400) != 0) { rx ^= 7; } // c + ((7 - x) & 7); } //Horr. flip + bmpdata[(ry << 9) + rx] = pal[tsetdat[pos++]]; + //pix >>= 4; + } + } + } + } + } + } + return PixelsToImage(bmpdata, 0x200, 0x400);// 0x100); + } + //private void tWin() { + // Form ts = new Form(); + // //ts.FormBorderStyle = FormBorderStyle.FixedToolWindow; + // ts.FormBorderStyle = FormBorderStyle.SizableToolWindow; + // ts.ClientSize = new Size(512, 769); //ts.Width = 512; ts.Height = 512; + // //ts.StartPosition = FormStartPosition.Manual;// Screen.PrimaryScreen.Bounds.Width - 512; + // //ts.SetDesktopLocation(Screen.PrimaryScreen.Bounds.Width - 525, 25); + // //ts.BackgroundImageLayout = ImageLayout.None; + // ts.AutoScroll = true; //Adds scrollbars to form. + // //ts.StartPosition + // ts.Show(this); + // PictureBox tspicBox1 = new PictureBox(); //System.Windows.Forms. + // tspicBox1.Size = new System.Drawing.Size(0x200, 0x400); + // ts.Controls.Add(tspicBox1); + // ((PictureBox)ts.Controls[0]).Image = dispTileset(); + //} + int tileDisp = 0; + Form ts = new Form(); int lastPressedKey = 0; + int hideLayer = 0; + void tWin(int controlSet, int showForm) { //showForm is temp arg??? //updateToolBox + //if (ts.Visible == true) { tspicBox1.Image = Map.dispTileset(); } + if (lastPressedKey != controlSet) + { + ts.Controls.Clear(); + lastPressedKey = controlSet; + } + else + { + + } + if (ts.IsDisposed || !ts.Visible) { + if (showForm == 0) { return; } + ts = new Form(); + //ts.FormBorderStyle = FormBorderStyle.FixedToolWindow; + ts.FormBorderStyle = FormBorderStyle.SizableToolWindow; + ts.ClientSize = new Size(529, 769); //ts.Width = 512; ts.Height = 512; //512,769 + //ts.StartPosition = FormStartPosition.Manual;// Screen.PrimaryScreen.Bounds.Width - 512; + //ts.SetDesktopLocation(Screen.PrimaryScreen.Bounds.Width - 525, 25); + //ts.BackgroundImageLayout = ImageLayout.None; + ts.AutoScroll = true; //Adds scrollbars to form. + //ts.StartPosition + ts.Show(this); //Setting the owner to "this" form makes windows stay in front of main form, but not in front of other apps like .TopMost. + ts.KeyDown += new KeyEventHandler(this.Form1_KeyDown); + //ts.MouseDown += new MouseEventHandler(this.tsDefocus); + + } + switch (controlSet) { + case 0x31: + case 0x32: + case 0x33: + if (ts.Controls.Count == 0) { //Init + PictureBox tspicBox1 = new PictureBox(); //System.Windows.Forms. + tspicBox1.Size = new System.Drawing.Size(0x200, 0x400); + ts.Controls.Add(tspicBox1); + //tsClick += new System.EventHandler(this.tsClick); + tspicBox1.MouseDown += new MouseEventHandler(this.tsClick); + tspicBox1.MouseMove += new MouseEventHandler(this.tsClick);//Move); + tspicBox1.Paint += new PaintEventHandler(this.tsPaint); + } + if (tileDisp == 0) + { + if (world_map == 1) + { + ((PictureBox)ts.Controls[0]).Image = dispTsetImgWM(rom[pos[0] + 7 + (controlSet - 0x31)] * 0x80); + } + else + { + ((PictureBox)ts.Controls[0]).Image = dispTsetImg(rom[pos[0] + 7 + (controlSet - 0x31)] * 0x80); + } + //if (showhmap == 1) + //{ + // showhmap = 0; + // dispMap(); + //} + } + else if (tileDisp == 1) + { + if (world_map == 1) + { + ((PictureBox)ts.Controls[0]).Image = dispTilesetWM(rom[pos[0] + 7 + (controlSet - 0x31)] * 0x4000); //tspicBox1.Image = Map.dispTileset(); + } + else + { + ((PictureBox)ts.Controls[0]).Image = dispTileset(rom[pos[0] + 7 + (controlSet - 0x31)] * 0x4000); //tspicBox1.Image = Map.dispTileset(); + } + } + else if (tileDisp == 2) + { + ((PictureBox)ts.Controls[0]).Image = PixelsToImage(pal, 16, 16, 32); + } + else if (tileDisp == 3) + { + ((PictureBox)ts.Controls[0]).Image = disphtable(); + //if (showhmap == 0) + //{ + // showhmap = 1; + // dispMap(); + //} + } + else if (tileDisp == 4) + { + ((PictureBox)ts.Controls[0]).Image = disptmedit(); + dispMap(); + } + ((PictureBox)ts.Controls[0]).Width = ((PictureBox)ts.Controls[0]).Image.Width; + ((PictureBox)ts.Controls[0]).Height = ((PictureBox)ts.Controls[0]).Image.Height; + break; + case 0x34: //Solidity + break; + case 0x37: //Area Scripts + if (ts.Controls.Count == 0) { + } + //loadAreaData(); + break; + case 0x38: //Warps + if (ts.Controls.Count == 0) { + } + + //if (((NumericUpDown)ts.Controls[1]).Value != 0) { //Commented because changing visibility of warp boxes will set to 0. + // ((NumericUpDown)ts.Controls[1]).Value = 0; + //} else { + // loadWarpData(); //Not sure of best way to trigger ValueChanged. :( + //} + break; + } + } + //int getHeight(int x, int y) + //{ + // return getHeight(x, y, 0); //TODO: Change 0. + //} + //int[] hv = { 0, 0, 0 }; //init once was not noticeably faster? + int getHeight(int x, int y, int htTile) + { + x &= 0xF; y &= 0xF; + int h = 0; + int[] hv = { // Height Values + ((htiles[htTile * 4 + 1] ^ 0x80) - 0x80) * 8, + ((htiles[htTile * 4 + 2] ^ 0x80) - 0x80) * 8, + ((htiles[htTile * 4 + 3] ^ 0x80) - 0x80) * 8 + }; + // Height Values + //hv[0] = ((htiles[htTile * 4 + 1] ^ 0x80) - 0x80) * 8; + //hv[1] = ((htiles[htTile * 4 + 2] ^ 0x80) - 0x80) * 8; + //hv[2] = ((htiles[htTile * 4 + 3] ^ 0x80) - 0x80) * 8; + + switch (htiles[htTile * 4] & 0xF) + { + case 0: // Flat ground + h = hv[0]; + break; + case 1: // Left/Right stairs + h = hv[0] + (((hv[1] - hv[0]) * x) >> 4); + break; + case 2: // North/South stairs + h = hv[0] + (((hv[1] - hv[0]) * y) >> 4); + break; + case 3: // / + h = hv[x + y >= 0x10 ? 1 : 0]; + break; + case 4: // \ + h = hv[y >= x ? 1 : 0]; + break; + case 5: + break; + case 6: + break; + case 7: // O + if (version == 1) + h = hv[0] + (hv[1] - hv[0]) * rom[0x2EDC4 + y * 0x10 + (x & 0xF)]; + break; + case 8: + h = hv[((x >> 3) & 1)]; + break; + case 9: + h = hv[(y >= 8 ? 1 : 0)]; + break; + case 0xD: + if (version == 1) + h = hv[rom[0x2EEC4 + y * 0x10 - (x & 0xF) + 0xF]]; + break; + case 0xE: + break; + case 0xF: + h = hv[(y >= 8 ? 1 : 0) + ((x | y) >= 8 ? 1 : 0)]; + break; + } + return h; + } + Bitmap disphtable() + { + int w = 256 * 16; + int h = 256 * 8 + 16 + 16 + 32; + int[] bmpdata = new int[w * h]; + for (int x = 0; x < 0x10 * 0x100; x++) + { + int dh = h; //draw height + for (int y = 15; y >= 0; y--) + { + //int fColor = 0x00f800; + //if (((htiles[(x >> 4) * 4] & 0xF) == 1) || ((htiles[(x >> 4) * 4] & 0xF) == 2)) + //{ + // fColor = 0xf8f800; //Yellow for stairs. + //} + int hy = h - 0x410 + y - getHeight(x, y, x >> 4); + //while (hy < dh - 12) + //{ + // bmpdata[--dh * w + x] = 0x800000; + //} + while (hy < dh - 12) + { + if (dh > (h - 0x410 + y)) + { + bmpdata[--dh * w + x] = 0xC00000; + } + else + { + if (dh <= 0) { break; } + bmpdata[--dh * w + x] = 0xf80000; + } + } + if (dh <= 0) { break; } + while (hy < dh - 8) + { + //bmpdata[--dh * w + x] = 0xf84000; + if (dh > (h - 0x410 + y)) + { + bmpdata[--dh * w + x] = 0xC04000; + } + else + { + bmpdata[--dh * w + x] = 0xf84000; + } + } + while (hy < dh) + { + //bmpdata[--dh * w + x] = 0xf88000; + if (dh > (h - 0x410 + y)) + { + bmpdata[--dh * w + x] = 0xC08000; + } + else + { + bmpdata[--dh * w + x] = 0xf88000; + } + } + if (hy == dh) + { + int fColor = 0x00f800; + if (((htiles[(x >> 4) * 4] & 0xF) == 1) || ((htiles[(x >> 4) * 4] & 0xF) == 2)) + { + fColor = 0xf8f800; //Yellow for stairs. + } + if (dh > (h - 0x410 + y)) + { + fColor &= 0xC0C000; + } + bmpdata[hy * w + x] = fColor; // 0x00f800; + } + } + } + //return disphmap();// (0); + return PixelsToImage(bmpdata, w, h); + } + Bitmap disphmap() + { + int l = lastPressedKey - 0x31; + if ((l < 0) || (l > 2)) { l = 0; } //{ return; } + int shiftx = rom[pos[0] + 0xC + (l * 8)], shifty = rom[pos[0] + 0xD + (l * 8)]; + int shift = (shiftx & 0xfe) + ((shifty & 0xfe) << 7); + if (nlmap != 0) + shift = 0; + int w = scnw;// 256 * 16; + int h = scnh;// 256 * 8 + 16 + 16; + //int[] bmpdata = new int[w * h]; + int mx = MousePosition.X - pictureBox1.PointToScreen(new Point(0, 0)).X; + int my = MousePosition.Y - pictureBox1.PointToScreen(new Point(0, 0)).Y;// - PointToScreen(new Point(0,picti + //int noPartial = 0; + //if ((mx < 0) || (mx > w) || (my < 0) || (my > h)) + // noPartial = 1; + for (int x = 0; x < w; x++) + { + int dh = h - 1; //draw height + for (int y = h - 1; y >= 0; y--) + { + int a = (shift >> 1) + (y >> 4) * 0x80 + (x >> 4); + if (a >= 0x4000) + continue; + int ht = 0;// = hmap[(shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + if (version == 0) + { + ht = tmap[0x4000 + (shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + } + else if (version == 1) + { + ht = hmap[(shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + } + int z = getHeight(x, y, ht); + int hy = y - z;// x >> 4); + if ((showhmap & 2) != 0) + hy = y; + if ((showhmap & 4) != 0) // && (noPartial == 0)) + { + if ((my >> 4) < (y >> 4)) + hy = y; + else + hy = y - z; + } + //if (y > (yp << 4)) + // hy = y; + if (hy < 0) //Floor cannot be drawn/goes off map. + continue; + if (hy > dh) //Floor is hidden. + { + //Quick fix + if (((dh + 1) * w + x) >= (scnw * scnh)) + continue; + bmpdata[(dh + 1) * w + x] = 0x000000; + continue; + } + int z2 = 0;// z - (dh - hy); + while (hy + 1 < dh) //Where to apply wall color for this (x,y) section. + { + int pixColor = 0x80 + z2++; + if (pixColor > 0xF0) + pixColor = 0xF0; + else if (pixColor < 0x0) + pixColor = 0x0; + + if (hy + 12 + 1 < dh) //Red wall + pixColor = 0x010000 * pixColor; //0xC00000; + else if (hy + 8 + 1 < dh) //Drop wall + pixColor = 0x010000 * pixColor + 0x002000; //0xC04000; + else if (hy + 1 < dh) //Climb wall + pixColor = 0x010000 * pixColor + 0x004000; //0xC08000; + + //bmpdata[dh * w + x] = pixColor; + //bmpdata[dh * w + x] = blendit(bmpdata[dh * w + x], pixColor, 0x1, 0x10); + bmpdata[dh * w + x] = pixColor + ((bmpdata[dh * w + x] >> 4) & 0x0F0F0F); //blendit(bmpdata[dh * w + x], pixColor, 0x1, 0x10); + dh--; + } + if (hy < dh) //Floor color + { + int pixColor = 0x80 + z; + if (pixColor > 0xF0) + pixColor = 0xF0; + else if (pixColor <= 0x0) + pixColor = 0x0; + + if (((htiles[(ht) * 4] & 0xF) == 1) || ((htiles[(ht) * 4] & 0xF) == 2)) //Stairs + pixColor = 0x010100 * pixColor; + else //Flat Floor + pixColor = 0x000100 * pixColor; + + //bmpdata[dh * w + x] = pixColor; + //bmpdata[dh * w + x] = blendit(bmpdata[dh * w + x], pixColor, 0x1, 0x10); //pixColor; + bmpdata[dh * w + x] = pixColor + ((bmpdata[dh * w + x] >> 4) & 0x0F0F0F); + dh--; + } + } + } + //dispPrioMap(); + return null;// PixelsToImage(bmpdata, w, h); + } + Bitmap disptmedit() + { + int[] bmpdata = new int[0x80000]; + int w = 0x200; + int h = 0x400; + int y = 0; + //Layer switching + for (int k = 0; k < 0x40; k += 16) + { + for (int i = 0; i < 16; i++) + { + for (int j = k; j < k + 16; j++) + { + bmpdata[i * w + j] = k << 2;//(j >> 4) << 6; + } + } + } + y += 0x10; + //Sprite Priority + for (int k = 0; k < 0x40; k += 16) + { + for (int i = y; i < y+ 16; i++) + { + for (int j = k; j < k + 16; j++) + { + bmpdata[i * w + j] = k << 2;//(j >> 4) << 6; + } + } + } + y += 0x10; + //Event ID + for (int l = 0; l < 0x100; l += 16) + { + for (int k = 0; k < 0x100; k += 16) + { + for (int i = y; i < y + 16; i++) + { + for (int j = k; j < k + 16; j++) + { + bmpdata[i * w + j] = 0x202020 + (l<<15) + (k>>1);//(j >> 4) << 6; + } + } + } + y += 0x10; + } + for (int l = 0; l < 0x80; l += 16) + { + for (int k = 0; k < 0x20; k += 16) + { + for (int i = y; i < y + 16; i++) + { + for (int j = k; j < k + 16; j++) + { + bmpdata[i * w + j] = 0x202020 + (l << 15) + (k >> 1);//(j >> 4) << 6; + } + } + } + y += 0x10; + } + + return PixelsToImage(bmpdata, 0x200, 0x400); ; + } + Bitmap dispPrioMap() //Nevermind Prio, but I'll just use it for now b/c I'm bad with names. + { + int l = lastPressedKey - 0x31; + if ((l < 0) || (l > 2)) { l = 0; } //{ return; } + int shiftx = rom[pos[0] + 0xC + (l * 8)], shifty = rom[pos[0] + 0xD + (l * 8)]; + int shift = (shiftx & 0xfe) + ((shifty & 0xfe) << 7); + if (nlmap != 0) + shift = 0; + int w = scnw;// 256 * 16; + int h = scnh;// 256 * 8 + 16 + 16; + //int[] bmpdata = new int[w * h]; + //int mx = MousePosition.X - pictureBox1.PointToScreen(new Point(0, 0)).X; + //int my = MousePosition.Y - pictureBox1.PointToScreen(new Point(0, 0)).Y;// - PointToScreen(new Point(0,picti + //int noPartial = 0; + //if ((mx < 0) || (mx > w) || (my < 0) || (my > h)) + // noPartial = 1; + + for (int row = 0; row < (scnh); row += 16) + { + for (int col = 0; col < (scnw); col += 16) + { + //int t = Bits.getInt16(tmap, 0x8000 + dx + shift + (dy << 7)) & 0xFFF; + if (0x8000 + (col >> 3) + shift + (row << 4) > 0x10000) + break; + int t = 0;// = Bits.getInt16(tmap, 0x8000 + (col >> 3) + shift + (row << 4));// >> 0xE; + //try { + //if ((t & 0x800) != 0) + // MessageBox.Show(t.ToString("X4")); + //int color2 = 0; + if (tey < 0x10) + { + int i = 0x8001 + ((col >> 4) << 1) + shift + ((row >> 4) << 8); + //tmap[i] = (byte)((tmap[i] & 0xCF) | ((tex >> 4) << 4)); + t = (tmap[i] &0x30) << 2; + } + else if (tey < 0x20) + { + int i = 0x8001 + ((col >> 4) << 1) + shift + ((row >> 4) << 8); + //tmap[i] = (byte)((tmap[i] & 0x3F) | ((tex >> 4) << 6)); + t = (tmap[i] & 0xC0); + } + else if (tey < 0x120) + { + //tmap[0x0000 + ((col >> 4)) + shift + ((row >> 4) << 7)] = (byte)(((tey - 0x20) & 0xF0) | (tex >> 4)); + int i = 0x0000 + ((col >> 4)) + (shift >> 1) + ((row >> 4) << 7); + t = tmap[i]; + //t |= (0xF0 - t) << 16; + t = ((t & 0xF0) << 15) | ((t & 0xF) << 3); + //if (tmap[i] == 0xFB) + // color2 = 0xFFFFFF; + } + else if (tey < 0x1A0) + { + int i = 0x4000 + ((col >> 4)) + (shift >> 1) + ((row >> 4) << 7); + t = (tmap[i] >> ((tey - 0x120) >> 4)) & 1; + t <<= 6; + } + int color = t;//|color2;// & 0x3000; + //if ((0x8000 + (col >> 3) + shift + (row << 4)) == 0x8e40)//0x9C80) // 0xA440) + // if (color == 0) + // color = 0xffffff; + for (int y = row; y < row + 16; y++) + { + for (int x = col; x < col + 16; x++) + { + //bmpdata[y * w + x] = color; + bmpdata[y * w + x] = color + ((bmpdata[y * w + x] >> 4) & 0x0F0F0F); + } + } + } + } + //for (int x = 0; x < w; x++) + //{ + // int dh = h - 1; //draw height + // for (int y = h - 1; y >= 0; y--) + // { + // int ht = hmap[(shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + // } + //} + return null;// PixelsToImage(bmpdata, w, h); + } + + int t8ind = 0; + int t16ind = 0; + int palind = 0; + int tex = 0, tey = 0; + void tsClick(object sender, MouseEventArgs e) { + if (MouseButtons != MouseButtons.Left) { return; } + if (tileDisp == 0) + { + int a = rom[pos[0] + 7 + (lastPressedKey - 0x31)] * 0x80; + if ((e.Y < a) || ((a + 0x100) <= e.Y)) { return; } + if ((e.X < 0) || (0x100 <= e.X)) { return; } + t8ind = (((e.Y - a) >> 3) << 5) | (e.X >> 3); + } + else if (tileDisp == 1) + { + t16ind = ((e.Y >> 4) << 5) | (e.X >> 4); + } + else if (tileDisp == 2) + { + palind = ((e.Y >> 5) << 4) | (e.X >> 5); + ColorDialog cd = new ColorDialog(); + if (cd.ShowDialog() == DialogResult.OK) + { + pal[palind] = cd.Color.ToArgb() & 0x00F8F8F8; + + uint p = (uint)pal[palind]; + p = (p << 0x8 >> 0x1B) | (p << 0x10 >> 0x1B << 5) | (p << 0x18 >> 0x1B << 10); + Bits.setInt16(paldat, palind * 2, (int)p); + byte[] temp = new byte[0x10000]; + temp[0] = 1; //Compression Type 01 + int size = Comp.compressFormat1(paldat, 0, temp, 1)[1]; + size = (size + 3) & ~3; + Array.Resize(ref temp, size); + insertMFTfile(palfind, temp); + + tWin(lastPressedKey, 0); + dispMap(); //loadEntireMap(); + } + } + else if (tileDisp == 3) + { + hind = e.X >> 4; + if ((Control.ModifierKeys & Keys.Control) != 0) //if (hind == e.X >> 4) + { + ((PictureBox)ts.Controls[0]).Invalidate(); + string input = Bits.getInt32(htiles, hind * 4).ToString("X8"); + if (ShowInputDialog(ref input) == DialogResult.OK) + { + Bits.setInt32(htiles, hind * 4, Convert.ToInt32(input, 16)); + ((PictureBox)ts.Controls[0]).Image = disphtable(); + } + } + } else + { + tex = e.X; + tey = e.Y; + dispMap(); //In case a different overlay should display. + } + ((PictureBox)ts.Controls[0]).Invalidate(); + //tWin(lastPressedKey, 0); + } + int hind = 0; + void tsPaint(object sender, PaintEventArgs e) { + if (tileDisp == 0) { + int a = rom[pos[0] + 7 + (lastPressedKey - 0x31)] * 0x80; + e.Graphics.DrawRectangle(new Pen(Brushes.Red), (t8ind & 0x1F) << 3, a + (((t8ind >> 5) & 0x1F) << 3), 7, 7); + } else if (tileDisp == 1) { + e.Graphics.DrawRectangle(new Pen(Brushes.Red), (t16ind & 0x1F) << 4, ((t16ind >> 5) & 0x1F) << 4, 15, 15); + } + else if (tileDisp == 2) + { + } + else if (tileDisp == 3) + { + e.Graphics.DrawRectangle(new Pen(Brushes.Cyan), (hind & 0xFF) << 4, 0, 15, 0x104 * 8 - 1); + } + else if (tileDisp == 4) + { + e.Graphics.DrawRectangle(new Pen(Brushes.Cyan), tex & ~ 0xF, tey & ~0xF, 15, 15); + } + } + int mxp = 0, myp = 0; + int onClick = 0; //0=No click, 1=Just clicked, 2=Still clicked. //int mxClick = 0, myClick = 0; + void mapClick(object sender, MouseEventArgs e) { //MouseDown and MouseMove + if ((MouseButtons == MouseButtons.Left) || (MouseButtons == MouseButtons.Right)) + onClick += 1; + else + onClick = 0; + if (onClick > 2) //0 or 2 if called from MouseMove ; 1 if MouseDown. + onClick = 2; + //Return if on same tile, because we don't want to slow things down doing redundant actions. + if ((mxp >> 4 == e.X >> 4) && (myp >> 4 == e.Y >> 4)) + { + mxp = e.X; myp = e.Y; + if (onClick != 1) + return; + } + mxp = e.X; myp = e.Y; + if ((showhmap & 4) != 0) + dispMap(); + //Return if not Left mouse button was moved down. + + //if ((mxClick >> 4 == e.X >> 4) && (myClick >> 4 == e.Y >> 4)) + //{ + // mxClick = e.X; myClick = e.Y; + // return; + //} + //int layiOffset = 1 << (3 - l); + // int shiftx = rom[pos[0] + 0xC + (l * 8)], shifty = rom[pos[0] + 0xD + (l * 8)]; + // int shift = (shiftx & 0xfe) + ((shifty & 0xfe) << 7); + // for (int row = 0; row < (scnh); row += 16) { + // for (int col = 0; col < (scnw); col += 16) { + // //int t = Bits.getInt16(tmap, 0x8000 + dx + shift + (dy << 7)) & 0xFFF; + // int t = (Bits.getInt16(tmap, 0x8000 + (col >> 3) + shift + (row << 4)) & 0xFFF) * 8; + + int l = lastPressedKey - 0x31; + if ((l < 0) || (l > 2)) { return; } + int shiftx = rom[pos[0] + 0xC + (l * 8)], shifty = rom[pos[0] + 0xD + (l * 8)]; + int shift = (shiftx & 0xfe) + ((shifty & 0xfe) << 7); + if (nlmap != 0) + shift = 0; + if ((e.X < 0) || (e.Y < 0)) + return; + if ((e.X >= scnw) || (e.Y >= scnh)) + return; + int t = 0; + byte[] mapdata = null; //World Map + int cSize = 0; + if (world_map == 1) + { + mapdata = new byte[0x400]; + int wmpos = Bits.getInt32(rom, 0x680000 + 4 * 0x197) & 0x1FFFFFF; + int iOffset = (((e.Y >> 8) * (scnw >> 8)) + (e.X >> 8)) * 4; + int rptr = Bits.getInt32(rom, wmpos + iOffset); //iOffset += 4; + if (rptr == 0) + return; + cSize = Comp.decompressf(rom, wmpos + rptr, mapdata, 0x0000, 1)[0] - rptr - wmpos; //Map data + + //t = Bits.getInt16(mapdata, (((e.X & 0xFF) >> 4) << 2) + shift + (((e.Y & 0xFF) >> 4) << 8)); + t = Bits.getInt16(mapdata, (((e.X & 0xFF) >> 4) << 2) + (((e.Y & 0xFF) >> 4) << 6)); + } + else + { + t = Bits.getInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8));// & 0xF000) | t16ind; + //MessageBox.Show(e.X.ToString()); + } + if (MouseButtons == MouseButtons.Right) + { + t16ind = t & 0xFFF; + ((PictureBox)ts.Controls[0]).Invalidate(); + return; + } + if (MouseButtons != MouseButtons.Left) + { + return; + } + + if (tileDisp == 0) + { //Check if replacing tile is in use, then insert tile if enough space. + //if (((xp >> 3) == (e.X >> 3)) && ((yp >> 3) == (e.Y >> 3))) { return; } + //xp = e.X; yp = e.Y; + + // Bits.setInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8), t); + //for (int i = 0; i < 0x8000; i+= 2) Bits.setInt16(tmap, i + 0x8000, i); + byte[] data = new byte[8]; + for (int i = 0; i < 8; i++) + { + data[i] = stiles[((t & 0xFFF) * 8) + i]; + } + //TODO: CHANGE DATA + //(t8ind & 0x1F) << 3, a + (((t8ind >> 5) & 0x1F) << 3) + int j = ((e.Y & 8) >> 1) + ((e.X & 8) >> 2); + data[j] = (byte)t8ind; + data[j + 1] = (byte)(t8ind >> 8); + + int t8a = 0; while (t8a < (t8amt * 8)) + { + int i = 0; while (i < 8) + { + if (stiles[t8a + i] != data[i]) { break; } + i++; + } + if (i == 8) { break; } + // //if (i < 8) { continue; } break; + t8a += 8; + } + if ((t8a >> 3) < 0x800) + { + if (t8a == (t8amt * 8)) + { + for (int i = 0; i < 8; i++) + { + stiles[(t8amt * 8) + i] = data[i]; + } + t8amt++; + } + Bits.setInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8), (t & 0xF000) | (t8a >> 3)); + //Bits.setInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8), (t & 0xF000) | t16ind); + //ind[t] = t8amt++; //If code is un-commented, make ind[t] = t8a>>3. (Outside if loop.) + } + dispMap(); + } + else if (tileDisp == 1) + { //Just set tile. + //if (((xp >> 4) == (e.X >> 4)) && ((yp >> 4) == (e.Y >> 4))) { return; } + //xp = e.X; yp = e.Y; + if ((t & 0xFFF) == t16ind) { return; } + if (world_map == 1) + { + Bits.setInt16(mapdata, (((e.X & 0xFF) >> 4) << 2) + (((e.Y & 0xFF) >> 4) << 6), t16ind); + //mapdata = new byte[0x800]; + int wmpos = Bits.getInt32(rom, 0x680000 + 4 * 0x197) & 0x1FFFFFF; + int wmpos2 = Bits.getInt32(rom, 0x680000 + 4 * 0x198) & 0x1FFFFFF; + int wmsize = wmpos2 - wmpos; + int iOffset = (((e.Y >> 8) * (scnw >> 8)) + (e.X >> 8)) * 4; + int rptr = Bits.getInt32(rom, wmpos + iOffset); //iOffset += 4; + //int rptr = Bits.getInt32(rom, wmpos + iOffset); //iOffset += 4; + if (rptr == 0) + return; + byte[] data = new byte[0x800]; + int cSize2 = Comp.compressFormat1(mapdata, 0, data, 0)[1]; + int relSize = cSize2 - cSize; + + if (relSize > 0) + { + MessageBox.Show(">0"); + offsetMFT(0x197, wmsize + relSize); + for (int i = wmsize - 1; (rptr + cSize) < i; i--) + { + rom[wmpos + i + relSize] = rom[wmpos + i]; + } + } + else + { + MessageBox.Show("<0"); + for (int i = (rptr + cSize); i < wmsize; i++) + { + rom[wmpos + i + relSize] = rom[wmpos + i]; + } + offsetMFT(0x197, wmsize + relSize); + } + + //Change pointers + for (int i = wmpos + iOffset + 4; i < wmpos + 0x2000; i += 4) + { + int j = Bits.getInt32(rom, i); + if (j != 0) + Bits.setInt32(rom, i, j + relSize); + } + + //Insert data + for (int i = 0; i < cSize2; i++) + { + rom[wmpos + rptr + i] = data[i]; + } + + //Comp.decompressf(rom, wmpos + rptr, mapdata, 0x0000, 1); //Map data + + //t = Bits.getInt16(mapdata, (((e.X & 0xFF) >> 4) << 2) + shift + (((e.Y & 0xFF) >> 4) << 8)); + //t = Bits.getInt16(mapdata, (((e.X & 0xFF) >> 4) << 2) + (((e.Y & 0xFF) >> 4) << 6)); + } + else + { + //t = Bits.getInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8));// & 0xF000) | t16ind; + //MessageBox.Show(e.X.ToString()); + Bits.setInt16(tmap, 0x8000 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8), (t & 0xF000) | t16ind); + } + //for (int i = 0; i < 0x8000; i+= 2) Bits.setInt16(tmap, i + 0x8000, i); + dispMap(); + } + else if (tileDisp == 2) //Palette + { + } + else if (tileDisp == 3) //H-table + { + if (version == 0) + { + //ht = tmap[0x4000 + (shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + tmap[0x4000 + ((e.X >> 4) << 0) + (shift >> 1) + ((e.Y >> 4) << 7)] = (byte)hind; + } + else if (version == 1) + { + //ht = hmap[(shift >> 1) + (y >> 4) * 0x80 + (x >> 4)]; + hmap[((e.X >> 4) << 0) + (shift >> 1) + ((e.Y >> 4) << 7)] = (byte)hind; + } + dispMap(); + } + else if (tileDisp == 4) + { + if (tey < 0x10) + { + int i = 0x8001 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8); + tmap[i] = (byte)((tmap[i] & 0xCF) | ((tex >> 4) << 4)); + } + else if (tey < 0x20) + { + int i = 0x8001 + ((e.X >> 4) << 1) + shift + ((e.Y >> 4) << 8); + tmap[i] = (byte)((tmap[i] & 0x3F) | ((tex >> 4) << 6)); + } + else if (tey < 0x120) + { + tmap[0x0000 + ((e.X >> 4)) + (shift >> 1) + ((e.Y >> 4) << 7)] = (byte)(((tey - 0x20) & 0xF0) | (tex >> 4)); + } + else if (tey < 0x1A0) + { + int i = 0x4000 + ((e.X >> 4)) + (shift >> 1) + ((e.Y >> 4) << 7); + tmap[i] = (byte)((tmap[i] & ~(1 << ((tey - 0x120) >> 4))) | ((tex >> 4) << ((tey - 0x120) >> 4))); + } + dispMap(); + } + //sortTiles(); //Re-organize tiles. + //insertMFTmapfiles(); + } + int t8amt = 0; + void sortTiles() { + int[] freq = new int[0x1000]; + int[] ind = new int[0x1000]; + byte[] stiles2 = new byte[0x10000]; + t8amt = 0; + for (int ti = 0x8000; ti < 0x10000; ti += 2) { + int ta = Bits.getInt16(tmap, ti); + int t = ta & 0xFFF; + if (freq[t] == 0) { + //int t8a = 0; while (t8a < (t8amt * 8)) { + // int i = 0; while (i < 8) { + // if (stiles2[t8a + i] != stiles[t * 8 + i]) { break; } + // i++; + // } + // if (i == 8) { break; } + // //if (i < 8) { continue; } break; + // t8a += 8; + //} + //if (t8a == (t8amt * 8)) { + for (int i = 0; i < 8; i++) { + stiles2[(t8amt * 8) + i] = stiles[t * 8 + i]; + } + ind[t] = t8amt++; //If code is un-commented, make ind[t] = t8a>>3. (Outside if loop.) + //} + //t = t8a >> 3; + //Bits.setInt16(tmap, ti, (ta & 0xF000) | (t8a >> 3)); + //Bits.setInt16(tmap, ti, (ta & 0xF000) | t8amt); + } + Bits.setInt16(tmap, ti, (ta & 0xF000) | ind[t]); + freq[t]++; + } + stiles = stiles2; + } + + void copy(byte[] src, int srcPos, byte[] des, int desPos, int size) + { + for (int i = 0; i < size; i++) + { + des[desPos + i] = src[srcPos + i]; + } + //return desPos + size; + } + //void copycompfile(byte[] data, int desPos, int fileRef) //Copy compressed file. //Thought it'd be easier to do in parent function. + //{ + // if (fileRef == 0) + // { + // Bits.setInt32(data, desPos, 0); + // return; + // } + // copy(rom, addr, data, 0, 0x40); + //} + void insertMFTmapfiles() + { //int index) { + int index = mapfind; + //indexaddr = 0x680000 + index * 4; + int addr = Bits.getInt32(rom, 0x680000 + index * 4) & 0x1ffffff; + //int addr2 = Bits.getInt32(rom, 0x680000 + index * 4 + 4) & 0x1ffffff; + + //byte[] stiles; byte[] tmap; + byte[] mapdata = new byte[0x10000]; + //byte[] cttable = new byte[0x8000]; + + copy(rom, addr, mapdata, 0, 0x40); + int desPos = 0x40; + byte[] temp = new byte[0x10000]; + for (int i = 0; i < 7; i++) + { + int fileRef = Bits.getInt32(rom, addr + 0x24 + i * 4); + if (fileRef == 0) + { + Bits.setInt32(mapdata, 0x24 + i * 4, 0); + continue; + } + Bits.setInt32(mapdata, 0x24 + i * 4, desPos); + if (i == 2) + { + mapdata[desPos++] = 1; + desPos = Comp.compressFormat1(tmap, 0, mapdata, desPos)[1]; + desPos += 3; + desPos &= ~3; + continue; + } + else if (i == 3) + { + mapdata[desPos++] = 1; + desPos = Comp.compressFormat1(hmap, 0, mapdata, desPos)[1]; + desPos += 3; + desPos &= ~3; + continue; + } + int srcPos1 = addr + fileRef; + int srcPos2 = Comp.decompress(rom, srcPos1, temp, 0)[0]; //Only care about compressed size. (srcPos2=after compressed file) + int size = srcPos2 - srcPos1; + copy(rom, srcPos1, mapdata, desPos, size); + desPos += size; + desPos += 3; + desPos &= ~3; + } + + Array.Resize(ref mapdata, desPos); + insertMFTfile(index, mapdata); + //mapdata[desPos++] = 1; + + //int ctmsize = Comp.compressFormat1(tmap, 0, ctmap, 1)[1]; + //int cttsize = Comp.compressFormat1(stiles, 0, cttable, 1)[1]; + + //decompTileData(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x24)), stiles, 0); //8x8 tile table - Decompress & Deobfuscate. + //Height Tile Data - Skip for now. + //decompMap2(rom, pos[0] + (Bits.getInt32(rom, pos[0] + 0x2C)), tmap, 0); //16x16 tilemap - Decompress & Deobfuscate. + //Height Tilemap - Skip for now. + //Animation + + + //int size = ctmsize + cttsize; + + //offsetMFT(index, size); + + //int addr = pos[0]; + //while (true) + //{ + + //} + + } + + private void toolStripButton7_Click(object sender, EventArgs e) + { + toolStripButton7.Text = "Processing..."; + toolStrip1.Update(); + //toolStripButton7.Invalidate(); + insertMFTmapfiles(); + toolStripButton7.Text = "Done"; + } + + private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) + { + + } + + int offsetMFT(int index, int size) //Makes it so the file at this index has this size. + { + //Get info for what data to move and by how much... etc. + byte[] temp = new byte[0x10000]; + int entryaddr = 0x680000 + 2047 * 4; + int lastfileaddr = 0; + while (true) { + lastfileaddr = Bits.getInt32(rom, entryaddr); + if (lastfileaddr != 0) break; + entryaddr -= 4; + } + int eofaddr = Comp.decompress(rom, lastfileaddr & 0x1ffffff, temp, 0)[0]; + index = 0x680000 + index * 4; + int addr = Bits.getInt32(rom, index) & 0x1ffffff; + int addr2 = Bits.getInt32(rom, index + 4) & 0x1ffffff; + int offset = size - (addr2 - addr); + //MessageBox.Show(eofaddr.ToString("x8")); + //Move contents to either remove the gap or make enough space for the file. + if (offset < 0) + { + int i; + for (i = addr2; i < eofaddr; i++) + { + rom[i + offset] = rom[i]; + } + while ((i+offset) < eofaddr) + { + rom[i++ + offset] = 0; + } + } + else if (offset > 0) + { + if (0xF79650 < eofaddr + offset) + { + //MEGAROMS Bootleg really shouldn't be in here. Shame! So let's delete it the way it should be! Happy editing! + if (Bits.getInt32(rom, 0x468) == 0x08F9EE50) + { + Bits.setInt32(rom, 0x468, 0x0801319D); + for (int i = eofaddr; i < 0xF9EFE8; i++) + { + rom[i] = 0; + } + } + } + //Check to make sure we're just overwriting 0s. + for (int i = eofaddr; i < eofaddr + offset; i++) + { + if (rom[i] != 0) + { + string hex = ""; + for (int j = i & ~3; j < i + 0x80; j+=0x10) + { + hex += "\n" + string.Format("{0} {1} {2} {3}", + Bits.getInt32(rom, j).ToString("X8"), + Bits.getInt32(rom, j + 0x4).ToString("X8"), + Bits.getInt32(rom, j + 0x8).ToString("X8"), + Bits.getInt32(rom, j + 0xC).ToString("X8")); + } + if (MessageBox.Show("Okay to overwrite data at " + i.ToString("X8") + "? (" + eofaddr.ToString("X8") + "-" + (eofaddr + offset).ToString("X8") + ")\nSample data:" + hex,"Overwrite?",MessageBoxButtons.OKCancel) == DialogResult.Cancel) + { + return -1; + } + else + { + break; + } + } + } + //Move the data. + for (int i = eofaddr - 1; addr2 <= i; i--) + { + rom[i + offset] = rom[i]; + } + } + //Update the pointer list! + //for (int i = index + 4; i <= entryaddr; i += 4) + //{ + // Bits.setInt32(rom, i, Bits.getInt32(rom, i) + offset); + //} + + //Update the pointer list! (v2 - Assumes not all files are in order.) + int startRange = Bits.getInt32(rom, index); + int endRange = eofaddr | 0x08000000; + for (int i = 0x680000; i <= entryaddr; i += 4) + { + int ptr = Bits.getInt32(rom, i); + if ((ptr > startRange) && (ptr < endRange)) + { + Bits.setInt32(rom, i, ptr + offset); + } + } + return addr; + } + void insertMFTfile(int index, byte[] data) + { + int addr = offsetMFT(index, data.Length); + if (addr == -1) + return; + //Actually insert the file for real! + for (int i = 0; i < data.Length; i++) + { + rom[addr + i] = data[i]; + } + } + + private static DialogResult ShowInputDialog(ref string input) + { + System.Drawing.Size size = new System.Drawing.Size(200, 70); + Form inputBox = new Form(); + + inputBox.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + inputBox.ClientSize = size; + inputBox.Text = "Input"; + + System.Windows.Forms.TextBox textBox = new TextBox(); + textBox.Size = new System.Drawing.Size(size.Width - 10, 23); + textBox.Location = new System.Drawing.Point(5, 5); + textBox.Text = input; + inputBox.Controls.Add(textBox); + + Button okButton = new Button(); + okButton.DialogResult = System.Windows.Forms.DialogResult.OK; + okButton.Name = "okButton"; + okButton.Size = new System.Drawing.Size(75, 23); + okButton.Text = "&OK"; + okButton.Location = new System.Drawing.Point(size.Width - 80 - 80, 39); + inputBox.Controls.Add(okButton); + + Button cancelButton = new Button(); + cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + cancelButton.Name = "cancelButton"; + cancelButton.Size = new System.Drawing.Size(75, 23); + cancelButton.Text = "&Cancel"; + cancelButton.Location = new System.Drawing.Point(size.Width - 80, 39); + inputBox.Controls.Add(cancelButton); + + inputBox.AcceptButton = okButton; + inputBox.CancelButton = cancelButton; + + DialogResult result = inputBox.ShowDialog(); + input = textBox.Text; + return result; + } + } +} \ No newline at end of file diff --git a/Form1.resx b/Form1.resx new file mode 100644 index 0000000..cd2ff25 --- /dev/null +++ b/Form1.resx @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 237, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + 342, 17 + + \ No newline at end of file diff --git a/HexEditor.cs b/HexEditor.cs new file mode 100644 index 0000000..d131318 --- /dev/null +++ b/HexEditor.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using System.Windows.Forms; +using System.Drawing; //Point, Size + +//using System.Drawing; //Bitmap/Rectangle +using System.Drawing.Imaging; //PixelFormat +using System.Runtime.InteropServices; //Marshal + +namespace gsmagic +{ + class HexEditor + { + Form tt = new Form(); + int scnw = 800; + int scnh = 600; + PictureBox pictureBox1 = new PictureBox(); + public void init() + { + pictureBox1.Location = new Point(0, 0);// x + tbx.Width, y); + pictureBox1.Width = scnw;// bn.Width = 50; + pictureBox1.Height = scnh;// bn.Height = 20; + //bn.Font = Globals.font; + //bn.Text = "Edit"; + //bn.Click += button_Click; + tt.Controls.Add(pictureBox1); + tt.KeyDown += new System.Windows.Forms.KeyEventHandler(KeyDown); + tt.Show(); + } + private void KeyDown(object sender, KeyEventArgs e) + { + //MessageBox.Show(e.KeyData.ToString()); + switch (e.KeyCode) + { + case (Keys)0x20: //space bar + //romi -= 0x100; + if (romi < 0) + romi = 0; + //nBytes = 4; + xStart = 10 + nBytes * 16; + xa = -16; + xb = nBytes * -xa * 2 + -xa; //150; + //xStart = 10 + nBytes * -xa; + break; + case (Keys)0x21: //page up + //romi += 0x100; + xa = -16; + xb = -16; + //xStart = 10 + 16 * -xa; + xStart = 10 + 16 * 16 + ((16 / nBytes) - 1) * 16; //(16 >> (nBytes - 1)) - 1 + break; + } + disp(); + } + int nBytes = 4; + int xa = -16; + int xb = 0; + int xStart = 0; + int romi = 0; + public void disp() + { + int[] bmpdata = new int[scnw * scnh]; + + //BD + for (int i = 0; i < (scnw * scnh); i += 0x1) + { + bmpdata[i] = 0x006888; // 0x102080; + } + //for (int y = 0; y < scnh; y += 0x1) + //{ + // for (int x = 0; x < scnw; x += 0x1) + // { + + // } + //} + byte[] rom = Globals.mainForm.rom; + //drawStringI("Say, say, say, hey, hey now, baby! -Adam Levine/Maroon 5", bmpdata, 10, 10); + //int nBytes = 4; + ////int xStart = 10 + nBytes * 16; + ////int xa = -16; + ////int xb = 150; + ////int xStart = 10 + nBytes * -xa; + + //int xa = -16; + //int xb = -8; + //int xStart = 10 + 16 * -xa; + + //int nextNumberX = 150; //224; + int romi = this.romi; + for (int y = 0; y < 16; y++) + { + int xx = xStart; + drawStringI(romi.ToString("X8"), bmpdata, 10, 30 + y * 12); + xx += 100; + for (int x = 0; x < 16;) //Byte column + { + //int xx = 10 + x * nextNumberX; + //xx += nBytes * 20; + //xx += nextNumberX; + + //for (int a = nBytes; a > 0; a--) + //{ + //xx += xa; //-16; // int xx = 10 + x * nextNumberX + a * 8; + //drawStringI((rom[y * 16 + x]).ToString("X2"), bmpdata, 10 + x * 24, 30 + y * 12); + drawStringI((rom[romi] & 0xF).ToString("X1"), bmpdata, xx + 8, 30 + y * 12); + drawStringI((rom[romi++] >> 4).ToString("X1"), bmpdata, xx, 30 + y * 12); + x++; + + xx += xa; + //} + if ((x & (nBytes - 1)) == 0) + xx += xb; // nextNumberX; + } + } + pictureBox1.Width = scnw; pictureBox1.Height = scnh; + pictureBox1.Image = PixelsToImage(bmpdata, scnw, scnh); + } + public static Bitmap PixelsToImage(int[] array, int width, int height) + { + Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); + Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); + BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat); + IntPtr pNative = bitmapData.Scan0; + Marshal.Copy(array, 0, pNative, width * height); + bitmap.UnlockBits(bitmapData); + return bitmap; + } + void drawStringI(string text, int[] bmpdata, int x, int y) + { + //MessageBox.Show(((byte)text[1]).ToString()); + //0805A4E0 = Italics font + byte[] rom = Globals.mainForm.rom; + for (int stri = 0; stri < text.Length; stri++) + { + int chri = (byte)text[stri] - 0x20; + for (int yi = 0; yi < 14; yi++) + { + int row = Bits.getInt16(rom, 0x5A4E0 + (chri * 0x20) + 2 + (yi * 2)); + for (int xi = 0; xi < 14; xi++) + { + if ((row & 0x8000) != 0) + { + bmpdata[(y + yi) * scnw + (x + xi)] = 0xF8F8F8; + bmpdata[(y + yi + 1) * scnw + (x + xi + 1)] = 0; + } + row <<= 1; + } + } + x += Bits.getInt16(rom, 0x5A4E0 + (chri * 0x20)); + } + } + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..bfdeaa9 --- /dev/null +++ b/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace gsmagic { + static class Program { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9b53fb8 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("gsmagic")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("gsmagic")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e66b7844-468d-41ca-807c-bbcf012fba47")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..c485019 --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34014 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace gsmagic.Properties { + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if ((resourceMan == null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("gsmagic.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs new file mode 100644 index 0000000..a66dcc0 --- /dev/null +++ b/Properties/Settings.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace gsmagic.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.1.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string LastRom { + get { + return ((string)(this["LastRom"])); + } + set { + this["LastRom"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public int Runs { + get { + return ((int)(this["Runs"])); + } + set { + this["Runs"] = value; + } + } + } +} diff --git a/Properties/Settings.settings b/Properties/Settings.settings new file mode 100644 index 0000000..4a4aca2 --- /dev/null +++ b/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + + + + 0 + + + \ No newline at end of file diff --git a/Sub-editors/!subeditor.cs b/Sub-editors/!subeditor.cs new file mode 100644 index 0000000..d562765 --- /dev/null +++ b/Sub-editors/!subeditor.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace gsmagic +{ + abstract class subeditor + { + //public string text; + public abstract string text(); + public abstract void load(TabControl tabControl1); + } +} diff --git a/Sub-editors/eClass.cs b/Sub-editors/eClass.cs new file mode 100644 index 0000000..c63d194 --- /dev/null +++ b/Sub-editors/eClass.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +namespace gsmagic//.Sub_editors +{ + class eClass : subeditor + { + Form1 test = Globals.mainForm; + byte[] txt = Globals.editorsForm.txt; + //new string text = "Classes"; + public override string text() + { + return "Classes"; + } + public override void load(TabControl tabControl1) + { + Table_Manager tm = new Table_Manager(); + tm.setTable(test.rom, 0xC15F4, 0x54); + tm.setPanel(tabControl1.SelectedTab);// tabPage5); + int w = tabControl1.SelectedTab.Width; + int h = tabControl1.SelectedTab.Height; + + //class Type Labels + //List ctlbl = new List(); + //Shouldn't need more than 256 types if not doing code hacks to increase the number of classes. (e.g. Class index is saved in 8-bit.) + //var ctlbl = Enumerable.Repeat(0, 256).ToList(); //If using a List. + var ct = new int[0x100]; + for (int i = 2915 - 2915; i < 3159 - 2915; i++) + { + int n = Bits.getInt32(test.rom, 0xC15F4 + i * 0x54); + if (n >= 0x100) + continue; + if (ct[n] == 0) //{ } + ct[n] = 2915 + i; + } + var ctstr = new string[0x100];//new List();// + for (int i = 0; i < 0x100; i++) //{ } + if (ct[i] != 0) + ctstr[i] = (i.ToString().PadLeft(3, ' ') + "|" + Bits.getTextShort(txt, ct[i])); + else + { + ct[i] = -1; + ctstr[i] = i.ToString().PadLeft(3, ' ') + "|"; + } + + //2915 + //List items = new List(); + //for (int i = 2915; i < 3159; i++) + //{ + // items.Add((i - 2915).ToString().PadLeft(3, ' ') + "|" + getTextStrShort(i)); + //} + List items = new List(); + for (int i = 0; i < 3159 - 2915; i++) + { + items.Add(2915 + i); + } + tm.doTableListbox(txt, items);// items); + + int pnlx = w / 2 - 200 + 100 + 25; + int pnly = 20 + 100;// tabPage8.Height / 2 - 125; + pnly += 20; + tm.doNamebox(pnlx, pnly - 30, txt, 2915); + + String[] psyNames = new String[734]; + for (int ind2 = 0; ind2 < 734; ind2++) + { + psyNames[ind2] = ind2.ToString().PadLeft(3, ' ') + "|" + Bits.getTextShort(txt, 1447 + ind2); + } + + Label fi = tm.doLabel(pnlx, pnly, "Class Type"); + //tm.doNud(pnlx + 100, pnly, 0, 32); + tm.doCombo(pnlx + 100, pnly, txt, ct.ToList(), 0, 32); + pnly -= 30; + //fi = tm.doLabel(pnlx, pnly + 60, "Elemental Level Requirements"); + //fi.Width = 500; + string[] eNames = { "Venus", "Mercury", "Mars", "Jupiter" }; + for (int i = 0; i < 4; i++) + { + tm.doLabel(pnlx + i * 100, pnly + 60, eNames[i] + " Lv."); + tm.doNud(pnlx + i * 100, pnly + 80, 4 + i, 8); + } + + string[] percents = new string[0x100]; + for (int i = 0; i < 0x100; i++) + { + percents[i] = (i * 10) + "%"; + } + pnlx -= 50; + tm.doLabel(pnlx, pnly + 200 - 80, "HP:"); + Control combo = tm.doCombo(pnlx + 80, pnly + 200 - 80, Bits.textToBytes(percents), Bits.numList(0x100), 0x8, 8); + combo.Width = 70; + tm.doLabel(pnlx, pnly + 200 - 60, "PP:"); + combo = tm.doCombo(pnlx + 80, pnly + 200 - 60, Bits.textToBytes(percents), Bits.numList(0x100), 0x9, 8); + combo.Width = 70; + + tm.doLabel(pnlx + 150 + 10, pnly + 200 - 80, "Attack:"); + combo = tm.doCombo(pnlx + 150 + 80 + 10, pnly + 200 - 80, Bits.textToBytes(percents), Bits.numList(0x100), 0xA, 8); + combo.Width = 70; + tm.doLabel(pnlx + 150 + 10, pnly + 200 - 60, "Defense:"); + combo = tm.doCombo(pnlx + 150 + 80 + 10, pnly + 200 - 60, Bits.textToBytes(percents), Bits.numList(0x100), 0xB, 8); + combo.Width = 70; + + tm.doLabel(pnlx + 300 + 20, pnly + 200 - 80, "Agility:"); + combo = tm.doCombo(pnlx + 300 + 80 + 20, pnly + 200 - 80, Bits.textToBytes(percents), Bits.numList(0x100), 0xC, 8); + combo.Width = 70; + tm.doLabel(pnlx + 300 + 20, pnly + 200 - 60, "Luck:"); + combo = tm.doCombo(pnlx + 300 + 80 + 20, pnly + 200 - 60, Bits.textToBytes(percents), Bits.numList(0x100), 0xD, 8); + combo.Width = 70; + + pnlx += 50; + tm.doLabel(pnlx - 50, pnly + 200 - 20, "Level"); + tm.doLabel(pnlx + 60 - 50, pnly + 200 - 20, "Ability"); + for (int i = 0; i < 8; i++) + { + Control lv = tm.doNud(pnlx - 50, pnly + 200 + i * 20, 0x10 + 2 + i * 4, 8); + lv.Width = 60; + tm.doCombo(pnlx + 60 - 50, pnly + 200 + i * 20, Bits.textToBytes(psyNames), Bits.numList(734), 0x10 + 0 + i * 4, 16); + } + tm.doLabel(pnlx + 200, pnly + 200 - 20, "Level"); + tm.doLabel(pnlx + 60 + 200, pnly + 200 - 20, "Ability"); + for (int i = 0; i < 8; i++) + { + Control lv = tm.doNud(pnlx + 200, pnly + 200 + i * 20, 0x10 + 2 + (8 + i) * 4, 8); + lv.Width = 60; + tm.doCombo(pnlx + 60 + 200, pnly + 200 + i * 20, Bits.textToBytes(psyNames), Bits.numList(734), 0x10 + 0 + (8 + i) * 4, 16); + } + Label lbl = tm.doLabel(pnlx, pnly + 370, "Effect Weaknesses (+25% chance for non-flat effects.)"); + lbl.Width = 400; + for (int i = 0; i < 3; i++) + { + tm.doNud(pnlx + i * 100, pnly + 390, 0x50 + i, 8); + } + pnly = 0; //pnly -= 110; + //pnlx += 5; + //Class Type Chart + Table_Manager tm2 = new Table_Manager(); + tm2.setTable(test.rom, 0xC6604, 0x40); + tm2.setPanel(tabControl1.SelectedTab); //tabPage5); + for (int i = 0; i < 4; i++) + tm2.doLabel(pnlx + (i * 115), pnly, eNames[i]); + for (int j = 0; j < 4; j++) + tm2.doLabel(pnlx - 70, pnly + j * 20 + 20, eNames[j]); + pnly += 20; + //for (int j = 0; j < 4; j++) + // for (int i = 0; i < 4; i++) + // tm2.doNud(pnlx + (i * 100), pnly + j * 20, (j * 4 + i) * 4, 32); + for (int j = 0; j < 4; j++) + for (int i = 0; i < 4; i++) + { + Control ctrl = tm2.doCombo(pnlx + (i * 115), pnly + j * 20, txt, ct.ToList(), (j * 4 + i) * 4, 32); + ctrl.Width = 115; + } + tm2.loadEntry(null, null); + } + } +} diff --git a/Table Manager.cs b/Table Manager.cs new file mode 100644 index 0000000..88b5106 --- /dev/null +++ b/Table Manager.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; //Control +using System.Drawing; //Point, Size +namespace gsmagic +{ + class Table_Manager + { + List nuds = new List(); + List butls = new List(); + List dtbs = new List(); + + //List ctrls = new List(); + //List offsets = new List(); + //List bits = new List(); //Supports only multiples of 8 for now. + //List> itemsL = new List>(); // Should probably move this to custom controls? + + byte[] buf; + Control pnl; + int baseAddr = 0; + int entryLen = 0; + int entryAddr = 0; + Label cntAddr; + public void setPanel(Control panel) //Maybe just init stuff? + { + pnl = panel; + if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + combo2numeric = 1; + } + public void setTable(byte[] buffer, int baseA, int eLen) + { + buf = buffer; + baseAddr = baseA; + entryLen = eLen; + entryAddr = baseAddr; + } + + public SearchList sl = new SearchList(); + int combo2numeric = 0; + public void doTableListbox(byte[] txt, List items) //List items) + { + sl.doTableListbox(pnl, txt, items); + sl.lv.SelectedIndexChanged += new EventHandler(loadEntry); + if (entryLen != 0) // Entry length is "0" for text editor at present. + cntAddr = doLabel(240, 0, " "); + } + public void doTableListbox2(byte[] txt, List items) //List items) + { + sl.doTableListbox2(pnl, txt, items); + sl.lv.SelectedIndexChanged += new EventHandler(loadEntry); + if (entryLen != 0) // Entry length is "0" for text editor at present. + cntAddr = doLabel(240, 0, " "); + } + public Label doLabel(int x, int y, String text) + { + Label lbl = new Label(); + lbl.Location = new Point(x, y); + lbl.Size = new Size(text.Length * 8 + 8, 20); + //lbl.Size = new Size(100, 20); + lbl.Font = Globals.font; + //lbl.BackColor = Color.Beige; + lbl.Text = text; + pnl.Controls.Add(lbl); + //ctrls.Add(lbl); + return lbl; + } + public void loadEntry(object sender, EventArgs e) + { + int srcEntry = 0; + int entryAddr2 = entryAddr; + if (sender != null) + { + ListView lv = ((ListView)sender); + if (lv.SelectedIndices.Count != 1) { return; } + srcEntry = sl.sItems[lv.SelectedIndices[0]];//sortList[lv.SelectedIndices[0]]; + entryAddr2 = baseAddr + srcEntry * entryLen; + + //I want copy/paste entire entries functionality! Yay! + if (entryAddr != 0) //Ensuring that there is an item to copy. Also prevents CtrL+Shift form load bug because an item is selected on form load. + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) + if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift) + for (int i = 0; i < entryLen; i++) + buf[entryAddr2 + i] = buf[entryAddr + i]; + if (entryLen != 0) // Entry length is "0" for text editor at present. + cntAddr.Text = (0x8000000 | entryAddr2).ToString("X8"); + } + else { entryAddr = baseAddr; } + //int ind = ((ListBox)pnl.Controls[0]).SelectedIndex; + //int addr = 0xEDACC + ind * 0x1C; + //pnl.Controls[1].Text = (0x8000000 | addr).ToString("X8"); + for (int i = 0; i < nuds.Count; i++) + { + nuds[i].addr = nuds[i].addr - entryAddr + entryAddr2; + nuds[i].Value = Bits.getBits(nuds[i].buf, nuds[i].addr, nuds[i].bits); //nuds[i].getData(); + } + for (int i = 0; i < butls.Count; i++) + { + butls[i].addr = butls[i].addr - entryAddr + entryAddr2; + butls[i].Text = Bits.getTextShort(butls[i].txt, butls[i].items[Bits.getBits(butls[i].buf, butls[i].addr, butls[i].bits)]); + //butls[i].itemsL[Bits.getBits(butls[i].buf, butls[i].addr, butls[i].bits)].ToString(); + //butls[i].Text = Bits.getTextLong(txt, Bits.getBits(butls[i].buf, butls[i].addr, butls[i].bits)); + } + for (int i = 0; i < dtbs.Count; i++) + { + dtbs[i].theIndex = dtbs[i].baseIndex + srcEntry; + dtbs[i].tbx.Text = Bits.getTextLong(dtbs[i].txt, dtbs[i].theIndex); + } + entryAddr = entryAddr2; + //for (int i = 0; i < ctrls.Count; i++) + //{ + // if (ctrls[i].GetType() == typeof(ComboBox)) + // { + // ((ComboBox)ctrls[i]).SelectedIndex = Bits.getBits(buf, entryAddr + offsets[i], bits[i]); + // } + // if (ctrls[i].GetType() == typeof(ButtonL)) + // { + // ((ButtonL)ctrls[i]).Text = itemsL[i][Bits.getBits(buf, entryAddr + offsets[i], bits[i])].ToString(); + // } + // if (ctrls[i].GetType() == typeof(TextBox)) + // { + // ((TextBox)ctrls[i]).Text = Bits.getTextLong(txt, theIndex + srcEntry); + // } + //} + } + public NumericUpDown doNud(int x, int y, int offset, int numOfBits) + { + var dnud = new DataNud(); + NumericUpDown nud = dnud.doNud(pnl, x, y, buf, entryAddr + offset, numOfBits); + nud.MouseClick += new MouseEventHandler(nudrc2); + nuds.Add(dnud); + return nud; + } + private void nudrc2(object sender, MouseEventArgs e) + { + var dnud = (DataNud)sender; + nudrcMain(dnud.addr - entryAddr, dnud.bits); + } + private void nudrcMain(int offset, int bits) + { //Sorts main list based on data. + if ((Control.ModifierKeys & Keys.Control) != Keys.Control) + return; + if (sl == null) //Some error-proofing if you don't have a main list. + return; + //int k = nuds.IndexOf((DataNud)sender); //What we should sort by. + //var dnud = ((DataNud)sender); + for (int i = 0; i < sl.sItems.Count; i++) + { + int x = sl.sItems[i]; + int value = Bits.getBits(buf, baseAddr + x * entryLen + offset, bits); + int j = i; + while ((j > 0) && (Bits.getBits(buf, (baseAddr + sl.sItems[j - 1] * entryLen) + offset, bits) > value)) + { + sl.sItems[j] = sl.sItems[j - 1]; + j = j - 1; + } + sl.sItems[j] = x; + } + sl.lv.Invalidate(); + } + public Control doCombo(int x, int y, byte[] txt, List items, int offset, int numOfBits) + //public Control doCombo(int x, int y, string[] items, int offset, int numOfBits) + { + if (combo2numeric == 1) + { + return doNud(x, y, offset, numOfBits); + //return; + } + ButtonL bn = new ButtonL(); + bn.doCombo(pnl, x, y, txt, items, buf, entryAddr + offset, numOfBits); + bn.MouseClick += new MouseEventHandler(nudrc3); + butls.Add(bn); + return bn; + } + private void nudrc3(object sender, MouseEventArgs e) + { + var dnud = (ButtonL)sender; + nudrcMain(dnud.addr - entryAddr, dnud.bits); + } + //Textbox stuff for name editing purposes! (So def. link to text function?) + public DataTextbox doNamebox(int x, int y, byte[] textBuf, int index) + { + DataTextbox tbx = new DataTextbox(); + tbx.doTextbox(pnl, x, y, textBuf, index); + //tbx.Width = 180; + dtbs.Add(tbx); + + tbx.bn.Click += button_Click; + return tbx; + } + private void button_Click(object sender, EventArgs e) + { + //Comp.comptext(((DataTextbox)sender).txt, buf); //Assuming buf is the rom when name boxes are used? + sl.lv.Invalidate(); + } + } +} \ No newline at end of file diff --git a/VirtList.cs b/VirtList.cs new file mode 100644 index 0000000..3c9887a --- /dev/null +++ b/VirtList.cs @@ -0,0 +1,210 @@ +////using System; +////using System.Collections.Generic; +////using System.Linq; +////using System.Text; +////using System.Threading.Tasks; + +////namespace gsmagic { +//// class VirtList { +//// } +////} + + +//using System; +//using System.Collections; +//using System.Collections.Generic; + +//namespace VirtualListWithPagingTechnique { +// namespace VirtualLists { +// public interface IObjectGenerator { +// /// +// /// Returns the number of items in the collection. +// /// +// int Count { get; } + +// /// +// /// Generate the item that is located on the specified index. +// /// +// /// +// /// This method is only be called once per index. +// /// +// /// Index of the items that must be generated. +// /// Fresh new instance. +// T CreateObject(int index); +// } + +// /// +// /// Virtual lists are lists from which the content is loaded on demand. +// /// +// /// +// /// Use visual lists if it is expensive to populate the list and only +// /// a subset of the list's elements are used. The virtual list uses an +// /// object generator to populate the list on demand. +// /// +// /// Objects that are stored inside the list. +// public class VirtualList : IList, IList where T : class { +// #region Internal attributes +// /// +// /// Object that is used to generate the requested objects. +// /// +// /// +// /// This object can also hold a IMultipleObjectGenerator reference. +// /// +// private readonly IObjectGenerator _generator; + +// /// +// /// Internal array that holds the cached items. +// /// +// private readonly T[] _cachedItems; +// #endregion + +// #region Constructor +// /// +// /// Create the virtual list. +// /// +// /// +// public VirtualList(IObjectGenerator generator) { +// int maxItems = generator.Count; // Determine the number of items +// _generator = generator; // Save generator and items +// _cachedItems = new T[maxItems]; +// } +// #endregion + +// #region IList Members +// public int IndexOf(T item) { +// return IndexOf(item); +// } +// public void Insert(int index, T item) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public void RemoveAt(int index) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public T this[int index] { +// get { +// if (!IsItemCached(index)) // Cache item if it isn't cached already +// CacheItem(index); +// return _cachedItems[index]; // Return the cached object +// } +// set { throw new NotSupportedException("VirtualList is a read-only collection."); } +// } +// #endregion + +// #region ICollection Members +// public void Add(T item) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public void Clear() { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public bool Contains(T item) { +// return (IndexOf(item) != -1); +// } +// public void CopyTo(T[] array, int arrayIndex) { +// _cachedItems.CopyTo(array, arrayIndex); +// } +// public int Count { +// get { return _cachedItems.Length; } +// } +// public bool IsReadOnly { +// get { return true; } +// } +// public bool Remove(T item) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// #endregion + +// #region IEnumerable Members +// public IEnumerator GetEnumerator() { +// return new VirtualEnumerator(this); +// } +// #endregion + +// #region IList Members +// public int Add(object value) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public bool Contains(object value) { +// throw new NotImplementedException(); +// } +// public int IndexOf(object value) { +// int items = _cachedItems.Length; +// for (int index = 0; index < items; ++index) { +// if (_cachedItems[index].Equals(value)) // Check if item is found +// return index; +// } +// return -1; // Item not found +// } +// public void Insert(int index, object value) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// public bool IsFixedSize { +// get { return true; } +// } +// public void Remove(object value) { +// throw new NotSupportedException("VirtualList is a read-only collection."); +// } +// object IList.this[int index] { +// get { return this[index]; } +// set { throw new NotSupportedException("VirtualList is a read-only collection."); } +// } +// #endregion + +// #region ICollection Members +// public void CopyTo(Array array, int index) { +// _cachedItems.CopyTo(array, index); +// } +// public bool IsSynchronized { +// get { return false; } +// } +// public object SyncRoot { +// get { return this; } +// } +// #endregion + +// #region IEnumerable Members +// IEnumerator IEnumerable.GetEnumerator() { +// return new VirtualEnumerator(this); +// } +// #endregion + +// #region Internal helper methods required for caching +// private bool IsItemCached(int index) { +// return (_cachedItems[index] != null); // If the object is NULL, then it is empty +// } +// #endregion + +// public void CacheItem(int index) { +// _cachedItems[index] = _generator.CreateObject(index); // Obtain only a single object +// } + +// #region Internal IEnumerator implementation +// private class VirtualEnumerator : IEnumerator { +// private readonly VirtualList _collection; +// private int _cursor; +// public VirtualEnumerator(VirtualList collection) { +// _collection = collection; +// _cursor = 0; +// } +// public T Current { +// get { return _collection[_cursor]; } +// } +// object IEnumerator.Current { +// get { return Current; } +// } +// public bool MoveNext() { +// if (_cursor == _collection.Count) // Check if we are behind +// return false; +// ++_cursor; // Increment cursor +// return true; +// } +// public void Reset() { +// _cursor = 0; // Reset cursor +// } +// public void Dispose() { // NOP +// } +// } +// #endregion +// } +// } +//} \ No newline at end of file diff --git a/gsmagic.csproj b/gsmagic.csproj new file mode 100644 index 0000000..c2e7d1c --- /dev/null +++ b/gsmagic.csproj @@ -0,0 +1,115 @@ + + + + + Debug + AnyCPU + {2F536098-CFE3-4289-BB9A-890B40C2E663} + WinExe + Properties + gsmagic + gsmagic + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Component + + + + + Component + + + + Form + + + Editors.cs + + + Form + + + Form1.cs + + + + + + + + + + + + Editors.cs + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + \ No newline at end of file