• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
April 24, 2024, 07:16:43 am

News:

Use of ePSXe before 2.0 is highly discouraged. Mednafen, RetroArch, and Duckstation are recommended for playing/testing, pSX is recommended for debugging.


Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Darthatron

41
1) He doesn't have a menu sprite. It's stored differently to the animated sprites for walking and such. Only playable units have these (and also Mewt, if I recall correctly, implying that he was probably going to be playable at some point in development.)

2) I will look into this for you when I get a chance. I've been very busy with a new job and moving house over the past couple of months.

3) This is very strange... I can't imagine why. There must be some specific check. I'll see what I can find.

4) Yeah. There's a check for this. It makes it so characters you can't have or haven't got through normal methods (GameShark or something) don't gain exp. Change the byte at 12E5C3 from D9 to E0 in a hex editor. This will bypass all of the checks.
42
FFTA/FFTA2 Hacking / Re: Another Texttool
October 19, 2014, 06:16:24 pm
Nice! I wrote a C# function to compress LZSS. It's usually the same or better compression as the original. Maybe you can add it to save space.

public int LZSSDecompress(byte[] source, ref byte[] dest, out int inSize)
        {
            int retlen = source[3] | (source[2] << 0x08) | (source[1] << 0x10) | (source[0] << 0x18);
            int xIn = 4;
            int xOut = 0;
            int tmp = 0;
            int i = 0;
            int j = 0;

            while (xOut < retlen)
            {
                if ((source[xIn] & 0x80) == 0x80)
                {
                    tmp = (xOut - ((source[xIn] & 0x07) << 8)) - source[xIn + 1] - 1;

                    for (i = ((source[xIn] >> 3) & 0x0F) + 3; i > 0; i--)
                    {
                        dest[xOut] = dest[tmp];
                        xOut++;
                        tmp++;
                    }

                    xIn++;
                }
                else if ((source[xIn] & 0x40) == 0x40)
                {
                    for (i = (source[xIn] & 0x3F) + 1; i > 0; i--)
                    {
                        xIn++;
                        dest[xOut] = source[xIn];
                        xOut++;
                        if (xOut >= retlen) break;
                    }
                }
                else if ((source[xIn] & 0x20) == 0x20)
                {
                    for (i = (source[xIn] & 0x1F) + 2; i > 0; i--)
                    {
                        dest[xOut] = 0x00;
                        xOut++;
                        if (xOut >= retlen) break;
                    }
                }
                else if ((source[xIn] & 0x10) == 0x10)
                {
                    j = ((source[xIn + 1] & 0x3F) << 8) | source[xIn + 2];

                    tmp = (xOut - j) - 1;
                    if (tmp < 0) tmp = 0;

                    for (i = (((source[xIn + 1] >> 2) & 0x30) | (source[xIn] & 0x0F)) + 4; i > 0; i--)
                    {
                        dest[xOut] = dest[tmp];
                        tmp++;
                        xOut++;
                        if (xOut >= retlen) break;
                    }

                    xIn += 2;
                }
                else if (source[xIn] == 0x01)
                {
                    for (i = source[xIn + 1] + 3; i > 0; i--)
                    {
                        dest[xOut] = 0xFF;
                        xOut++;
                        if (xOut >= retlen) break;
                    }

                    xIn += 1;
                }
                else if (source[xIn] == 0x02)
                {
                    for (i = source[xIn + 1] + 3; i > 0; i--)
                    {
                        dest[xOut] = 0x00;
                        xOut++;
                        if (xOut >= retlen) break;
                    }

                    xIn += 1;
                }
                else if (source[xIn] == 0x00)
                {
                    j = source[xIn + 3] | (source[xIn + 2] << 0x08);
                    tmp = xOut - j - 1;
                    if (tmp < 0) tmp = 0;

                    for (i = source[xIn + 1] + 5; i > 0; i--)
                    {
                        dest[xOut] = dest[tmp];
                        xOut++;
                        if (xOut >= retlen) break;
                        tmp++;
                    }

                    xIn += 3;
                }

                xIn++;
            }

            inSize = xIn;
            return retlen;
        }


public int LZSSCompress(byte[] source, out byte[] dest)
        {
            List<byte> ret = new List<byte>();
            int xIn = 0;
            int xTemp = 0;
            int temp = 0;
            int size = source.Length;

            int zCount;
            int fCount;
            int notMatched;
            int length;
            int pos;

            //Big-endian Decompressed Size.
            ret.Add((byte)((size / 0x1000000) & 0xFF));
            ret.Add((byte)((size / 0x10000) & 0xFF));
            ret.Add((byte)((size / 0x100) & 0xFF));
            ret.Add((byte)(size & 0xFF));

            while (true)
            {
                if (xIn >= size) break;
                notMatched = 0;
                length = 0;
                pos = -1;
                xTemp = xIn;

                while (pos == -1)
                {
                    if (xTemp >= size) break;
                    pos = FindLongestSubArray(source, xTemp, out length);
                    if (pos != -1)
                    {
                        zCount = CompareBytes(source, xIn, notMatched - 1, 0x00, true);
                        fCount = CompareBytes(source, xIn, notMatched - 1, 0xFF, true);
                        if (notMatched == 1 && source[xIn] == 0x00 && source[xIn + 1] == 0x00) pos = -1;
                        else if (notMatched == 1 && source[xIn] == 0xFF && source[xIn + 1] == 0xFF && source[xIn + 2] == 0xFF) pos = -1;
                        else if (notMatched == 2 && source[xIn] == 0xFF && source[xIn + 1] == 0xFF) pos = -1;
                        else if (zCount > 0 && (temp = CompareBytes(source, xTemp, length, 0x00)) > 0)
                        {
                            if (zCount + temp >= 2)
                                pos = -1;
                        }
                        else if (fCount > 0 && (temp = CompareBytes(source, xTemp, length, 0xFF)) > 0)
                        {
                            if (fCount + temp >= 3) pos = -1;
                        }
                        else if (zCount == 00)
                        {
                            temp = CompareBytes(source, xTemp, length, 0x00);
                            if (temp >= length - 1 && temp >= 2) pos = -1;
                        }
                    }

                    if (pos == -1)
                    {
                        notMatched++;
                        xTemp++;
                    }
                }

                int zPos = -1;
                int fPos = -1;

                while (notMatched > 0)
                {
                    zPos = FindFirstInstanceOfArray(source, xIn, notMatched, 0x00, 2, out zCount);
                    fPos = FindFirstInstanceOfArray(source, xIn, notMatched, 0xFF, 3, out fCount);
                    //If there are FF or 00 arrays within the "uncompressed" data...
                    if (zCount >= 2 || fCount >= 3)
                    {
                        //00's
                        if (zPos < fPos && zPos > -1 || fCount < 3)
                        {
                            if (zPos > 0)
                            {
                                ret.Add((byte)(0x40 + ((zPos - 1) & 0x3F)));
                                if (xIn + zPos > size) zPos = size - xIn;
                                while (zPos > 0)
                                {
                                    ret.Add(source[xIn]);
                                    xIn++;
                                    notMatched--;
                                    zPos--;
                                }
                            }

                            if (zCount >= 2 && zCount <= 33)
                            {
                                zCount = (zCount - 2) & 0x1F;
                                ret.Add((byte)(0x20 | zCount));
                                notMatched -= (zCount + 2);
                                xIn += (zCount + 2);
                            }
                            else if (zCount >= 3)
                            {
                                ret.Add(0x02);
                                zCount = (zCount - 3) & 0xFF;
                                ret.Add((byte)(zCount));
                                notMatched -= (zCount + 3);
                                xIn += (zCount + 3);
                            }
                        }
                        //FF's
                        else
                        {
                            if (fPos > 0)
                            {
                                ret.Add((byte)(0x40 + ((fPos - 1) & 0x3F)));
                                if (xIn + fPos > size) fPos = size - xIn;
                                while (fPos > 0)
                                {
                                    ret.Add(source[xIn]);
                                    xIn++;
                                    notMatched--;
                                    fPos--;
                                }
                            }

                            if (fCount >= 3)
                            {
                                ret.Add(0x01);
                                fCount = (fCount - 3) & 0xFF;
                                ret.Add((byte)(fCount));
                                notMatched -= (fCount + 3);
                                xIn += (fCount + 3);
                            }
                        }
                    }
                    //Otherwise output all remaining data as uncompressed.
                    else
                    {
                        while (notMatched > 0x40)
                        {
                            ret.Add((byte)(0x7F));
                            temp = 0;
                            while (temp < 0x40)
                            {
                                ret.Add(source[xIn]);
                                xIn++;
                                notMatched--;
                                temp++;
                            }
                        }
                        ret.Add((byte)(0x40 + ((notMatched - 1) & 0x3F)));
                        if (xIn + notMatched > size) notMatched = size - xIn;
                        while (notMatched > 0)
                        {
                            ret.Add(source[xIn]);
                            xIn++;
                            notMatched--;
                        }
                    }
                }

                if (pos != -1)
                {
                    int distance = xIn - pos - 1;
                    switch (GetCompressionIndex(length, distance))
                    {
                        case 1: //Copy 3-18 bytes from close proximity
                            ret.Add((byte)(0x80 | (((length - 3) & 0x0F) << 3) | ((distance & 0x700) >> 8)));
                            ret.Add((byte)(distance & 0xFF));
                            break;
                        case 2: //Copy 4-67 bytes from medium proximity
                            ret.Add((byte)(0x10 | ((length - 4) & 0x0F)));
                            ret.Add((byte)((((length - 4) & 0x30) << 2) | ((distance & 0x3F00) >> 8)));
                            ret.Add((byte)(distance & 0xFF));
                            break;
                        case 3: //Copy 5-260 bytes from long proximity
                            ret.Add(0);
                            ret.Add((byte)(length - 5));
                            ret.Add((byte)((distance & 0xFF00) >> 8));
                            ret.Add((byte)(distance & 0xFF));
                            break;
                    }
                    xIn += length;
                }
            }

            dest = ret.ToArray();
            return ret.Count;
        }
43
Soon people will be calling me Da.
44
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 23, 2014, 02:03:55 am
Whoops. Do the same with the byte at 0C9BAA. I fixed my other post.

In regards to the different limits: In short, yes. But it's a bit complex as they are all compared against the same value at the moment.

EDIT: Actually with such a small value (149), you can do it. Changing the bytes at 0C9CAC from 53 49 to 95 21 will cap Speed at 149 (0x95 in Hexadecimal).
45
Actually I think items allow for negative speed values already. The issue is making it display in game, I think.
46
Quote from: rrs_kai on September 20, 2014, 06:07:50 amI am posting this here since the AIO 0.7 thread is old and Darthatron is the moderator here (is there any active thread where I can post this?)
1)Can skill names be changed in the AIO? if so how?
2)Can you also edit the skill descriptions from the AIO? or is there any other program which Eternal was referring to as "this requires use of Darthatron's new tools" that can be used for the editing descriptions
Is there any documentation/wiki where I can read about the AIO and other tools?...I only found FFT and FFTA2 on this sites wiki

Eternal is using the new version of AIO which is full of bugs and breaking ROMs. It will be released to the public ASAP. I recoded the whole thing so a lot is missing and a lot is broken. Text editing is (somewhat) functional.

There's a lot of info on the ROM on this wiki: http://datacrystal.romhacking.net/wiki/Final_Fantasy_Tactics_Advance
47
No no. Eternal can make a list of bugs that require changing of code or other things he isn't capable of. A lot of these bugs are things that can be edited in AIO.
48
FFTA/FFTA2 Hacking / Re: Editing special characters
September 18, 2014, 07:19:13 am
Well we can always change that code. I could look into it for you if you like.
49
Eternal, if you can compile a list of bugs which are my problem, I will get around to fixing them.
50
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 17, 2014, 09:10:05 pm
Fair enough.

Change the bytes at 12E658 from 25 0C to E5 0B. This will double the exp you get in battle.
51
FFTA/FFTA2 Hacking / Re: Editing special characters
September 17, 2014, 07:57:57 pm
Which Job did you give him? There's a check at the start of the job wheel code that checks if the unit is Cid, Babus or Ezel and lets them have only one job.
52
FFTA/FFTA2 Hacking / Re: Editing special characters
September 17, 2014, 01:47:23 am
So I've spent the last few days on and off trying to get the job wheel for Ezel and Babus include the Nu Mou jobs and I just can't seem to get it work. :(
53
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 17, 2014, 01:30:42 am
Quote from: Darien490 on September 17, 2014, 12:14:59 amAlso, is there a way to alter EXP and/or AP gains? Getting larger amounts of EXP might make a higher level cap more feasible. I know AP is given based on the mission, but I'm wondering if there's a quick-and-dirty method for increasing how much you get. That's not too important, though. If it's a matter of either editing the missions one-by-one or editing the ability requirements one-by-one, I might just deal with it as-is. And I'm guessing there's a hard limit for stats at 999?
That is a little bit harder. You could double it or half it pretty easily, but anything else become a lot more difficult. And doubling it kind of ruins the point of doubling the level cap, doesn't it?

And the reason it uses that equation is because the game handles the base stats of units somewhere random between 0.85 and 1.15 times the "Base". The growth is rounded up (to the nearest whole number) and multiplied by how the amount of times the unit "levels up"
54
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 17, 2014, 12:23:05 am
RoundDown(Base * 1.15) + Ceiling(Growth) * 49
55
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 17, 2014, 12:05:12 am
Quote from: Darien490 on September 16, 2014, 11:57:56 pm
Okay, cool. So, I know how to change the stat-growth stuff with the AIO editor. Is there an option somewhere in that program that I'm missing to change the level cap? Or do I need to alter the file manually?

Sorry I forgot to add that.

You say you get hex editing, yes? Change the byte at 0C9BAE from 32 to 63 to change the level cap the 99. Do the same with the byte at 0C9BAA.
56
FFTA/FFTA2 Hacking / Re: Raise the Level Cap
September 16, 2014, 08:12:00 pm
Quote from: Darien490 on September 16, 2014, 07:36:09 pm
I've always wondered if there was a way to raise the level cap, as I feel like 50 is too low. Is this possible? I have a basic understanding of hex editing, but when it comes to finding pointers and stuff, I'm clueless.

Yes it's relatively easy actually. The tedious part is then changing the stat-growth so stuff like the Blade-Biters and Jelly's don't become useless late-game when they hit 999 defence too early.
57
Quote from: ArcticPrism on September 16, 2014, 12:26:39 pm
Do you plan on doing stuff for FFTA2? The level scaling alone would be amazing. Lennart has some nice tools so just that would make me want to get started on modding that game.

No I don't plan on that at all at the moment. But I'm not going to rule it out.
58
Click this link and press "Go" and you will be connected to the IRC. :)

http://client01.chat.mibbit.com/?channel=%23ffh&server=irc.ffhacktics.com&nick=rrs_kai

It's just a chat room with people from this site.
59
Hey rrs_kai, I merged all of your posts. I appreciate your dedication to helping, but maybe try to keep it to one post every 12 hours (which you can edit as much as you like), so it doesn't get too cluttered.

Also feel free to join us on the IRC; Eternal and I are both frequently online there, so it may be easier to sort out some bugs that way.
60
FFTA/FFTA2 Hacking / Re: Editing special characters
September 09, 2014, 05:33:43 am
That's not how it works at all, actually. Which is why Ritz is treated as a Viera instead of a Human. This byte you're talking about for Babus and Ezel actually just makes them normal Nu Mou with a special sprite, but they lose their unique jobs.