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()); }
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 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()); }
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; } }
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 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; }
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); }
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); }
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()); }
//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") + "]"); } } }
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<int> ctlbl = new List<int>(); //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<String>();// 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<String> items = new List<String>(); //for (int i = 2915; i < 3159; i++) //{ // items.Add((i - 2915).ToString().PadLeft(3, ' ') + "|" + getTextStrShort(i)); //} List <int> items = new List <int>(); 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); }
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; }
//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<short, byte>(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()); }
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); }
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); }
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(); }
public static List <int> getTextMatches2(byte[] txt, String str, List <int> 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 <int> matchList = new List <int>(); 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); }
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); }