Golden Sun Hacking Community
18, April, 2021, 02:16:57 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: The last working version of the classic TLA Editor is Teawater's unofficial "mapeditor" draft.
 
  Home Forum DC Wiki Help Search Calendar Downloads Login Register  
  Show Posts
Pages: [1] 2 3 ... 112
1  Golden Sun Resources / Misc. GS Hacking / Re: problems with gstoolkit on: 11, March, 2021, 06:49:54 AM
Pretty much... and then Atrius made the one for GS2, and likely didn't test it.
If there are still problems after fixing the issue with the comment character (#), let me know. (If it still doesn't work, I will also want to ask what localization you are using? e.g. (U) version?)


Line 5060 in Atrius editor (appears blank)
The same line (#13C4) in gstoolkit appears as: #{00}

Quote from: Bold should not start with comment character.
#13C3 Lucky Medals{00}
Lucky Medals{00}
#13C4 #{00}
#{00}
#13C5 {1A}{01}: Toss{00}
{1A}{01}: Toss{00}
#13C6 {1A}{02}: Quit{00}
{1A}{02}: Quit{00}
2  Golden Sun Resources / Misc. GS Hacking / Re: problems with gstoolkit on: 13, February, 2021, 10:14:56 PM
is that the one where one of the lines start with a #? (Where # would be read as a comment character when it shouldn't be.)
3  Golden Sun Resources / The Classic GS Editor / Re: GSdatahandler decompile on: 12, January, 2021, 11:56:40 PM
Yep.
The DLL was coded in, I think C++?..... Those files can open in Notepad... but you may need a compiler to compile them.
The point of the DLL is because it executes faster than GML... It contains things like managing the ROM's free space, decompression, etc. (Not a whole lot.)
Most of the interesting stuff is in the .gmk file... which needs the Game Maker application to see.
4  Golden Sun Resources / Misc. GS Hacking / Re: Camelot's C compiler on: 12, January, 2021, 03:30:25 AM
There are still some functions that push/pop r4... such as from 08016E0C in GS2. (Relating to Save Game mechanics)

And also same for the audio section. (081C0000) ... We know Camelot uses the Sappy Engine... The code here looks kinda weird at times, though.... so it could have been compiled separately. (Kinda like how DLLs are.)
5  Golden Sun Hacking Community / Feedback / Re: Hi, guys, I want to remake part of GS but I need some help on: 27, September, 2020, 11:37:08 PM
Atrius's Editor was coded in GML, and the DLL it uses was coded in C++, yes. (DLL because GML is slow, and even then I still think GML is inefficient... and so... I made my incomplete/experiment gsmagic program. (Another GS editor... mainly for GS2, but needs a lot of work.)

___ROM hacking?___ (Warning: Text might be confusing for newbies, but I'm trying to give a gist without spending too much time explaining right now.)
If you want to do more with editing the GS ROMs, I'd suggest getting use to VBA's memory viewer and disassembler. (Under Tools.)  Also, maybe get a generic hex editor too. (I consider it optional since you can save dumps of ROM section from memory viewer.) ...  I don't expect anyone to learn it overnight. The disassembler shows thumb/arm (most of the time, you will want to read in thumb; arm is used too, but not a whole lot), which is the assembly language the code is in.
So if you learn that (GBATEK is also pretty necessary), then going a step further, you get to use a breakpoint debugger to help locate and document things a bit easier... I usually use SDL-H, but no$gba is good too.)
Taking all this in mind, this is what led up to me docing the data in my Google Docs. (GS2 is the most studied.)

___Rebuilding?___
Have you heard of OpenGoldenSun? -- Nevermind, I'm convinced that's a dead project.

BUT. There is someone else who was working on a project you might be interested in. = https://jjppof.github.io/goldensun_html5/
We are active on Discord, so that's also be a good place to contact the GSHC Community. (Including jjppof.)

-Teawater/Teaman
6  Golden Sun Hacking Community / Feedback / Re: Not all the sub-domains of the forum here are secure and could be easily hacked on: 30, July, 2020, 04:46:44 AM
Are we talking about SQL injection? (I would try it if I knew what I was doing... (so I can inform Sala/Kain/Atrius in PM) ... but I guess someone else can check. (Depending on whether it was already fixed or not.)

If that's the vuln and it was never fixed, I'd suggest looking into it right away.
7  General Hacking / Project List / Re: [RELEASE] Golden Sun Reloaded on: 24, July, 2020, 09:39:09 PM
Your English is wonderful.  You would have me fooled.  There may be a few very minor things like commas, but that's normal/everyone messes those up from time to time (including me)... and is most likely acceptable informally.

Quote
I already played this mod several times, and I just wanted to say that I adore it.
(Example - Connecting two sentences uses a comma and conjunction word.  Edit: Or alternately, a semi-colon. (;))


And I like how this is the only real active topic on this forum. :D :D.... What if we name this site to... Golden Sun Reloaded Community
8  Golden Sun Resources / GSMagic: The New Editor / Re: Where do I get GSMagic? on: 16, June, 2020, 09:27:33 PM
Sounds like you probably clicked the Editors button? That's only for GS2 right now.

For GS1, you should only be able to view maps. - Eventually, I shall get to doing more with it, but I'm often lazy, and could easily be a few years. =p
9  Golden Sun Resources / GSMagic: The New Editor / Re: Where do I get GSMagic? on: 03, June, 2020, 03:58:43 AM
That would be the latest "public" release, yes.
10  Golden Sun Hacking Community / Feedback / Christmas Theme on: 13, May, 2020, 09:01:51 PM
Is it possible to have the Christmas Theme year-round?  Is there a setting/Can one be made?
11  The Community / Introductions / Re: Hey everybody! I'm new! on: 26, April, 2020, 12:00:08 AM
Welcome! I will third Misery, and second Salanewt.
12  General Hacking / Project List / Re: A new Golden Sun Editor on: 12, April, 2020, 03:52:19 PM
Seems blank for Microsoft Edge and Internet Explorer. (Hopefully I'm not using outdated versions? *shrug*)

Seems to work with Google Chrome and Firefox, though. So that's good.
13  General Hacking / Project List / Re: A new Golden Sun Editor on: 11, April, 2020, 10:25:08 AM
You are welcome!
(FYI - Daddy Poi is a reference to that old guy in Kandarian temple (or whatever it is called.), and how a few of us joked about him on Discord way back. Heheh.)



Sounds like daddy boy to me, kinda.
14  General Hacking / Project List / Re: A new Golden Sun Editor on: 11, April, 2020, 09:50:07 AM
Might take a lot of screenshots to show everything... so won't go over everything right now, but I guess I can give you a few...

It may be kind of messy. - And plenty of work may need to be done.
But here's what Heightmap looks like. (You can also edit them too, if you are on the Height table page in subwindow.)
And here's what the Events may look like.

In both, it's done in three layers, so to see the other layers, hit 1/2/3 on keyboard. (Layers may be blank if it wasn't needed.)

And third image is what the subwindow looks like when you can put event tiles in the map. I have this here to also show that each tile lists the frequency of how often they were used in the map. (The tile uses a brighter color if the frequency is at least 1... with the exception of ID 0.)
The latest release version actually does 16 columns instead of 10.... but I decided to try 10, and I haven't finished fixing it. Heheh.



And the Editors windows is also kind of messy/needs work. Has a few tables, and I consider it slightly less interesting, so didn't include screenshots. (PLus, I'm limited to 4 per post, so...)
15  General Hacking / Project List / Re: [RELEASE] Golden Sun Reloaded on: 10, April, 2020, 11:52:18 PM
You found Magic River? (A known bug in the original.) Good job!
16  General Hacking / Project List / Re: A new Golden Sun Editor on: 10, April, 2020, 11:19:57 PM
Would be interesting to see if your project could completely replace gsmagic some day. I guess we'll see. I think I felt more comfortable working with C# than with Javascript, but if I get use to Javascript, then I guess it could work out.


Djinnis = Typo? "Djinn" would be the plural form. ("Djinni" is the singular.)
And I believe it to be pronounced as Jen/Jenny.
17  The Community / Tech, Gaming and Entertainment / Rumor: Metroid Fusion sequel coming to Switch? on: 10, April, 2020, 10:03:10 AM
So I'm reading that someone posted on Twitter back in January about a new Metroid and a new Paper Mario.

Thoughts?
18  General Hacking / Project List / Re: A new Golden Sun Editor on: 10, April, 2020, 09:26:26 AM
Aw. That's unfortunate.
Hm. Well. At least you figured out.
I have three versions of decompression routines for text myself. (All of which decompress all strings at once.)
Oh yeah, and all this is C#.
The main thing is that I don't account for char IDs of 0x100+. (GS2 (U) version does not have any chars from 0x100+ anyway.)

Spoiler for Offset Tree (My favorite one):
        static public byte[] decompText(byte[] src)
        { //, int srcInd) { // int srcPos) {
            //return decompTextOld2(src);
            int total = 0; int total2 = 0;
            DateTime c = DateTime.Now;
            //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;

            //Do a pre-scan of char tables to determine array sizes.
            int maxLetter = 0;
            int cTreeSize = 0;
            int maxDepth = 0;
            for (int char1 = 0; char1 <= maxLetter; char1++)
            {
                if ((char1 & 0xFF) == 0)
                {
                    chardata = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8) - 0x08000000;
                    charpntrs = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8 + 4) - 0x08000000;
                }
                //if (charpntrs == asmpchar) { break; }
                if (Bits.getInt16(src, charpntrs) == 0x8000) { charpntrs += 2; continue; }
                total2 += 1;
                int charTree = (chardata + Bits.getInt16(src, charpntrs)) << 3; charpntrs += 2;
                int charSlot = charTree - 12;
                int depth = 0;
                while (true)
                {
                    while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { depth++; cTreeSize++; }
                    int letter = ((Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF); charSlot -= 12; total += 1;
                    cTreeSize++;
                    if (letter > maxLetter) { maxLetter = letter; }
                    if (depth > maxDepth) { maxDepth = depth; }
                    //if ((char1 == 0) && (letter == 7))
                    //    Console.WriteLine("0-7 depth: " + depth);
                    if (depth <= 0) break;
                    --depth;
                } //while (depth > 0);
            }
            //Console.WriteLine("Total letter combos: " + total + "  \nTotal unique letters: " + total2 + "\nMax letter: " + maxLetter + "\nMax depth: " + maxDepth + "\ncTreeSize: " + cTreeSize);
 
            chardata = Bits.getInt32(src, asmpchar) - 0x08000000;
            charpntrs = Bits.getInt32(src, asmpchar + 4) - 0x08000000;
            int[] ctOffsets = new int[maxLetter + 1];// 0x1000];
            int[] cTree = new int[cTreeSize];// 0x10000];
            int[] nodeOffsets = new int[maxDepth]; //0x100]; //For temp use as we label leaves first, and iterate backwards.
            //int[] ctOffsets = new int[0x1000];
            //int[] cTree = new int[0x10000];
            //int[] nodeOffsets = new int[0x100]; //For temp use as we label leaves first, and iterate backwards.
            //int depth = 0;
            int pos = 0;
            for (int char1 = 0; char1 <= maxLetter; char1++)
            {
                if ((char1 & 0xFF) == 0)
                {
                    chardata = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8) - 0x08000000;
                    charpntrs = Bits.getInt32(src, asmpchar + (char1 >> 8) * 8 + 4) - 0x08000000;
                }
                //if (charpntrs == asmpchar) { break; }
                if (Bits.getInt16(src, charpntrs) == 0x8000) { charpntrs += 2; continue; }
                //total2 += 1;
                int charTree = (chardata + Bits.getInt16(src, charpntrs)) << 3; charpntrs += 2;
                int charSlot = charTree - 12;
                int depth = 0;

                ctOffsets[char1] = pos;
                while (true)
                {
                    while (((src[charTree >> 3] >> (charTree++ & 7)) & 1) == 0) { nodeOffsets[depth++] = pos++; }
                    cTree[pos++] = -((Bits.getInt16(src, charSlot >> 3) >> (charSlot & 7)) & 0xFFF); charSlot -= 12; //total += 1;

                    if (depth <= 0) break;
                    cTree[nodeOffsets[--depth]] = pos;
                } //while (depth > 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, textTree2 = textTree << 3;//, bitnum = 1, val = 0;
                do
                {
                    pos = ctOffsets[initChar];
                    while (cTree[pos] > 0)
                    {
                        if ((src[textTree2 >> 3] >> (textTree2++ & 7) & 1) == 0) { pos++; }
                        else { pos = cTree[pos]; }
                        //--- if using textTree2 = textTree; ---
                        //if (bitnum >= 0x100) { bitnum = 1; textTree2++; }
                        //if ((src[textTree2] & bitnum) == 0) { pos++; }
                        //else { pos = cTree[pos]; }
                        //bitnum <<= 1;
                    }
                    initChar = -cTree[pos]; //bitChar[entry]; val >>= bitLen[entry]; bitnum -= bitLen[entry];
                    des[desPos++] = (byte)initChar;
                    //if (srcI == 5468)
                    //    Console.Write(initChar.ToString("X2")+" ");
                } while (initChar != 0);
            }
            Console.WriteLine(DateTime.Now - c + " (Text Decompression!)");
            return des;
        }

Spoiler for Bit codes version:
        static public byte[] decompTextOld2(byte[] src) { //, int srcInd) { // int srcPos) {
            //return decompTextOld(src);
            int total = 0;
            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; total += 1;
                    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("Total: " + total);
            //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;
        }

Spoiler for Direct:
        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;
        }
(I'm not sure if this last one is what you mean by brute force or not.)



And my text compression function was huge... But I like it because it's fast.
Spoiler for Hidden:
        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") + " ");
                //}
            }
            /*//-------------------------------------------
            // Making spreadsheet of char tables! (Temp?)
            int[] bmp = new int[0x10000];
            System.Text.StringBuilder strbuild = new System.Text.StringBuilder(0x1000);
            for (int i = 0; i < 0x10000; i++)
            {
                if (freq == 0)
                    continue;
                strbuild.Append((i >> 8).ToString("X2") + (char)9 + (i & 0xFF).ToString("X2") + (char)9);
                strbuild.Append(freq);
                strbuild.Append((char)9);
                //strbuild.Append(bitCode);
                int j = i;
                //int j = 0;j = i & 0xFF00;
                //while (true)
                //{
                //    if (clst[j] == (i & 0xFF))
                //        break;
                //    j++;
                //}
                if (bitLen[j] > 0)
                    strbuild.Append(Convert.ToString(bitCode[j], 2).PadLeft(bitLen[j], '0'));
                strbuild.Append((char)9);
                strbuild.Append(bitLen[j]);
                strbuild.AppendLine();
                /*
                int color = 0xF8F8F8;
                if (((i >> 8) >= 0x41) && ((i >> 8) <= 0x5A))
                    color = 0x00F8F800;
                if (((i >> 8) >= 0x61) && ((i >> 8) <= 0x7A))
                    color = 0x00F8F800;
                if (((i >> 8) >= 0x30) && ((i >> 8) <= 0x39))
                    color = 0x00F8F800;

                if (((i & 0xFF) >= 0x41) && ((i & 0xFF) <= 0x5A))
                    color = 0x00F8F800;
                if (((i & 0xFF) >= 0x61) && ((i & 0xFF) <= 0x7A))
                    color = 0x00F8F800;
                if (((i & 0xFF) >= 0x30) && ((i & 0xFF) <= 0x39))
                    color = 0x00F8F800;

                if (color == 0x00F8F800)
                    color = 0x20A0F8;

                bmp = color;
               
            }
           
            System.Windows.Forms.PictureBox pb = new System.Windows.Forms.PictureBox();

            pb.Image = Bits.PixelsToImage(bmp, 256, 256);
            pb.Image.Save(@"C:\Users\tmttb\Desktop\usedchars.png");
           
            System.IO.File.WriteAllText(@"C:\Users\tmttb\Desktop\usedchars.txt", strbuild.ToString());
            *///-------------------------------------------

            //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;
            insAddr = (insAddr + 3) & -4;
            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());
        }
19  General Hacking / Project List / Re: A new Golden Sun Editor on: 10, April, 2020, 09:07:28 AM
That's great.
I'm not sure how well those run if you use WINE, but it might be an option.
I am happy to see someone besides me working on anything Editor related! So keep up the good work. And prepare for the huge challenge that it probably brings.
A Javascript version?  Can't wait to see it.
20  The Community / Open Discussion / Re: HELP!!! on: 01, April, 2020, 12:40:58 PM
In the event you only need to patch a single ips file, you don't necessarily need an IPS patching program. Since VBA has Auto-patching (if enabeled), which means that if the ROM and the IPS are in the same folder with the same name, VBA will patch it. (Not on the file itself, but on the copy it loaded.)
. (e.g. gs2.gba and gs2.ips)

@Android:
No idea. I only built it (gsmagic) with PC in mind.
But the program is open sourced, so if any changes are needed to make it work with Android, then by all means! :)
Just as clueless with Atrius's editor as well.
Maybe when I get another smart phone... or repair the one I messed up probably a year ago or so (probably won't bother? :Shrug:)...., I could probably consider looking into it.... or maybe I wouldn't need those. It's stuff I'd have to figure out.
Pages: [1] 2 3 ... 112
Chatbox
28, March, 2021, 06:10:33 PM
Salanewt: Tiny announcement down here that a new animation pack is now available for download! The Animation Overhaul is required; see the downloads page for more details.
03, March, 2021, 03:16:30 AM
Daddy Poi's Oily Gorillas: I'm happy ACE is possible and easy in GS1. :D Thank you Tret. Now if we can get GS2 Air's Rock to do ACE, wouldn't that be something.
18, February, 2021, 03:25:26 PM
Salanewt: The one here has everything: http://forum.goldensunhacking.net/index.php?action=downloads;sa=view;down=132
18, February, 2021, 02:03:20 PM
VardenSalad: It looks like Atrius' editor download is broken again. The only thing in the .zip is the background image
13, February, 2021, 03:15:41 PM
MaxiPower: Welcom back Charon. been a long time.
11, February, 2021, 09:40:04 PM
Daddy Poi's Oily GorillasSo how long is this site going to be "This website is still under construction, please excuse the mess." :D
04, February, 2021, 12:56:21 AM
charon the ferryman: LMAO i love 2010 tech
04, February, 2021, 12:56:07 AM
charon the ferryman: release me from my discord prison meme mortals
15, November, 2020, 03:45:26 PM
Salanewt: We're more alive than the board implies; most discussion takes place over on the Discord server.
15, November, 2020, 03:45:06 PM
Salanewt: Haha, heya!
15, November, 2020, 02:07:50 PM
Frog: Nice to see this place is still alive...ish anyway xD
30, October, 2020, 11:10:23 PM
Salanewt: ... Actually, it's almost time for me to post an update on the forum. It's been coming along really nicely overall, and it was only a couple months or so ago that I added some new status effects to the game.
30, October, 2020, 11:08:41 PM
Salanewt: I need to get it done to start making progress on the parts of the AI Overhaul I want to start working on.
30, October, 2020, 11:08:14 PM
Salanewt: It's going well! I wanted to get more of my djinn reform done this week but I've been busy with other things sadly.
30, October, 2020, 09:58:14 PM
KyleRunner: Hi guys! How are you doing?
13, October, 2020, 11:19:21 AM
MaxiPower: first chapter of my golden sun inspired webtoon is now live. be cool if yas could check it out. https://www.webtoons.com/en/challenge/legacy-of-the-lost-dragoon/the-northern-reaches/viewer?title_no=508487&episode_no=6
31, August, 2020, 08:40:32 AM
Daddy Poi's Oily Gorillas: Being able to convert IPS files to text files to also supporting commenting, and convert back to IPS after changes.... sounds like a fun strategy? 
27, August, 2020, 10:37:30 PM
Salanewt: Hey, thanks! 
25, August, 2020, 12:59:22 AM
Foreclosure: Yo! Looking forward for this AI OVerhaul patch when it's finished :) :) 
19, August, 2020, 07:00:17 PM
Salanewt: That's awesome! I'm pretty good; been working on an AI Overhaul project and have made some nice progress in the past couple weeks; the goal for tonight is to add Deadbeard to GS2 and then I can move onto something new.
19, August, 2020, 01:14:56 PM
Awec: Ye not bad, just checked back in for updates on GS Reloaded really. Although now I'm looking back through some of my old forum posts, which is fun :D how are you?
19, August, 2020, 01:43:07 AM
Salanewt: It sure is! How have you been?
16, August, 2020, 09:40:57 AM
Awec: Yo nice to see this forum is still going
14, August, 2020, 09:06:44 PM
Salanewt: Hey! How goes it?
01, August, 2020, 01:31:53 PM
KyleRunner: Hello, people!
08, July, 2020, 08:57:11 PM
Salanewt: That awkward feeling when almost a quarter of a year goes by without anyone posting a message in this chatbox.
27, April, 2020, 07:54:10 PM
Daddy Poi's Oily Gorillas: I'm having a thought. So I know Atrius's editor is slow at saving sprites.... So I've been thinking.   I am considering another console program.  This time, for importing and exporting sprites/animations. Image files (for sprites), binary files (for animation data), and maybe binary or text files for Settings. Would certainly be cool if it works out. - Console programs are fun, when you can (at least temporarily) cheat out making a full interface editor for them. =P
25, April, 2020, 10:42:07 PM
Daddy Poi's Oily Gorillas: Tried to list those in order of importance, but anyway....
25, April, 2020, 10:37:59 PM
Daddy Poi's Oily Gorillas: GSHC, GS Speedrunning, /r/Golden Sun, GS United Nations, ToK.  Sixth one is border-line I'm not sure.
25, April, 2020, 08:00:21 PM
Daddy Poi's Oily Gorillas: (low as in <100)

Affiliates
Temple of Kraden Golden Sunrise
Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.153 seconds with 20 queries.