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