Assembly Language: Things learned
Posted: Tue Feb 24, 2015 5:26 pm
Decided to make a new topic describing some of the things I discovered while debugging the game, in hopes that it will help others and maybe someone will pick it up and be able to take over should I disappear
The practices and behaviors stated here could help other people understand what the assembly code is doing in other games or the like.
This is also to show you why such a simple thing may take a long time to figure out haha. I'll start the most recent example since it's fresh.
Experience Table
So when you level up, you might think the game just looks up a table of how much experience you need for the next one; but you would be wrong in Legaia's case.
It uses a base experience table, but adds up each value until the count of values added is your level. For instance, if you're level 4, it adds the first four numbers together. Though it will do a bunch of calculating afterwords, let's start there. Here is the table.
1, 2, 3, 5, 7, 10, 14, 17,
21, 26, 31, 37, 43, 50, 57, 65,
73,82,91,101,111,122,133,145,
157,170,183,197,211,226,241,257,
273,290,307,325,343,362,381,401,
421,442,463,485,507,530,553,577,
601,626,651,677,703,730,757,785,
813,842,871,901,931,962,993,1025,
1057,1090,1123,1157,1191,1226,1261,1297,
1333,1370,1407,1445,1483,1522,1561,1601,
1641,1682,1723,1765,1807,1850,1893,1937,
1981,2026,2071,2117,2163,2210,2257,2305,
2353,2402
So already you can see it's not done so nicely. Let's do the example I used when discovering this. I had a save at level 31 leveling up to 32. So adding the first 31 numbers gives me the total of:
exp = 2631
Now time for a bunch of fun math equations (;_;) Lucky for you, I took all the assembly code which looks like this...
sll r2, r6, 0x04
addu r3, r2, r3
subu r3, r3, r6
sll r2, r3, 0x03
addu r3, r2, r3
addu r3, r3, r6
into fun math! yaaaay (not)
exp = (((exp << 4) - exp) << 3) + exp
O_o okay so I admit, that doesn't look any better. Now the << or >> mean to shift the binary numbers. Without getting into computer science, you can mathamatically think of it as multiplying or dividing by 2 to the power of said number. So 3 << 2 would mean 3 * 2^2 aka 3 * 4. So I break this down even further for you!
exp = exp * 121
Now our 2631 * 121 = 318,351 experience. This is what Vahn needs to level up again.
Now before you try to do any levels less than 16, guess what? There is code to check if the current level is less than 17 (aka 1-16) and it changes this calculation further! See ugly translated math below, and trust me, the assembly code for it is much much MUCH worse.
r3 = (exp << 5) - exp;
r2 = (((r3 << 6) - r3) << 3) + exp;
r3 = r2 << 2;
r2 += r3;
r2 = (r2 << 7) - exp;
r3 = 3,425,353,235; // this is just a hard coded number in the code
r7 = r2 * r3 >> 32;
exp = r7 >> 16;
All this can further be broken down to this: exp * 9,999,999 * 3,425,353,235 / 281474976710656
Look crazy right? In computer world, it's makes a little more sense.
exp * 9,999,999 * 0xcc2abe13 (hex). You'll get a large number, and it will overflow, so you just take the overflow value / 65536.
So if you plug 1 in, you get 121.
Level 2, plug 3 in and you get 365.
Annoying isn't it? I guess they did this to fix their exp calculations without changing the tables.
Okay if you're still reading at this point, you are clearly more crazy than I am. And I have a treat just for people like you....
Guess what??
That's only for VAHN. Now for Noa and Gala, the game further calculates a stunt growth to this!! Arrrgh.
Essentially, like every other stat in the game, Vahn is neutral or the base, and Noa/Gala are plus or minus an amount from him. Same with experience. The general rule is, Noa requires up to a percent less experience than Vahn to level up, and Gala requires up to a percent more. So their experience curves make it so Noa will level up ever so slightly faster and Gala ever so slightly slower
Here's that stunt table, at least what I call it...maybe a "modifier" table would be a better name for it:
125, 251, 376, 501, 625, 749, 872, 995,
1116,1237,1356,1474,1590,1705,1819,1930,
2040,2148,2254,2358,2460,2559,2656,2750,
2842,2931,3018,3101,3182,3259,3334,3405,
3473,3538,3600,3658,3713,3764,3812,3856,
3897,3933,3967,3996,4022,4043,4062,4076,
4086,4093,4095,4094,4089,4080,4068,4051,
4031,4007,3979,3947,3912,3873,3830,3784,
3734,3680,3624,3563,3500,3433,3363,3289,
3213,3134,3051,2966,2878,2787,2694,2598,
2500,2399,2296,2191,2084,1975,1864,1751,
1636,1520,1403,1284,1164,1043, 921, 799,
675,551
All the game does with this table is add or subtract a bit of experience depending if it's Noa or Gala. First the calculation to get the amount to modify.
exp * 20 / stunt
So if Noa, subtract the amount. If Gala, add the amount. They're usually around a percent or so difference.
And there you have it. The not so easy way of doing experience tables. So when I had to dump out these experience tables, there was no way to just pull it out of the game
I had to pull out the tables listed above, and build something quick to do the same calculations that the game does. Pain in my butt! Especially considering when I am home to do this stuff, it's usually real late and my brain hurts, haha!
This is also to show you why such a simple thing may take a long time to figure out haha. I'll start the most recent example since it's fresh.
Experience Table
So when you level up, you might think the game just looks up a table of how much experience you need for the next one; but you would be wrong in Legaia's case.
It uses a base experience table, but adds up each value until the count of values added is your level. For instance, if you're level 4, it adds the first four numbers together. Though it will do a bunch of calculating afterwords, let's start there. Here is the table.
1, 2, 3, 5, 7, 10, 14, 17,
21, 26, 31, 37, 43, 50, 57, 65,
73,82,91,101,111,122,133,145,
157,170,183,197,211,226,241,257,
273,290,307,325,343,362,381,401,
421,442,463,485,507,530,553,577,
601,626,651,677,703,730,757,785,
813,842,871,901,931,962,993,1025,
1057,1090,1123,1157,1191,1226,1261,1297,
1333,1370,1407,1445,1483,1522,1561,1601,
1641,1682,1723,1765,1807,1850,1893,1937,
1981,2026,2071,2117,2163,2210,2257,2305,
2353,2402
So already you can see it's not done so nicely. Let's do the example I used when discovering this. I had a save at level 31 leveling up to 32. So adding the first 31 numbers gives me the total of:
exp = 2631
Now time for a bunch of fun math equations (;_;) Lucky for you, I took all the assembly code which looks like this...
sll r2, r6, 0x04
addu r3, r2, r3
subu r3, r3, r6
sll r2, r3, 0x03
addu r3, r2, r3
addu r3, r3, r6
into fun math! yaaaay (not)
exp = (((exp << 4) - exp) << 3) + exp
O_o okay so I admit, that doesn't look any better. Now the << or >> mean to shift the binary numbers. Without getting into computer science, you can mathamatically think of it as multiplying or dividing by 2 to the power of said number. So 3 << 2 would mean 3 * 2^2 aka 3 * 4. So I break this down even further for you!
exp = exp * 121
Now our 2631 * 121 = 318,351 experience. This is what Vahn needs to level up again.
Now before you try to do any levels less than 16, guess what? There is code to check if the current level is less than 17 (aka 1-16) and it changes this calculation further! See ugly translated math below, and trust me, the assembly code for it is much much MUCH worse.
r3 = (exp << 5) - exp;
r2 = (((r3 << 6) - r3) << 3) + exp;
r3 = r2 << 2;
r2 += r3;
r2 = (r2 << 7) - exp;
r3 = 3,425,353,235; // this is just a hard coded number in the code
r7 = r2 * r3 >> 32;
exp = r7 >> 16;
All this can further be broken down to this: exp * 9,999,999 * 3,425,353,235 / 281474976710656
Look crazy right? In computer world, it's makes a little more sense.
exp * 9,999,999 * 0xcc2abe13 (hex). You'll get a large number, and it will overflow, so you just take the overflow value / 65536.
So if you plug 1 in, you get 121.
Level 2, plug 3 in and you get 365.
Annoying isn't it? I guess they did this to fix their exp calculations without changing the tables.
Okay if you're still reading at this point, you are clearly more crazy than I am. And I have a treat just for people like you....
Guess what??
That's only for VAHN. Now for Noa and Gala, the game further calculates a stunt growth to this!! Arrrgh.
Essentially, like every other stat in the game, Vahn is neutral or the base, and Noa/Gala are plus or minus an amount from him. Same with experience. The general rule is, Noa requires up to a percent less experience than Vahn to level up, and Gala requires up to a percent more. So their experience curves make it so Noa will level up ever so slightly faster and Gala ever so slightly slower
Here's that stunt table, at least what I call it...maybe a "modifier" table would be a better name for it:
125, 251, 376, 501, 625, 749, 872, 995,
1116,1237,1356,1474,1590,1705,1819,1930,
2040,2148,2254,2358,2460,2559,2656,2750,
2842,2931,3018,3101,3182,3259,3334,3405,
3473,3538,3600,3658,3713,3764,3812,3856,
3897,3933,3967,3996,4022,4043,4062,4076,
4086,4093,4095,4094,4089,4080,4068,4051,
4031,4007,3979,3947,3912,3873,3830,3784,
3734,3680,3624,3563,3500,3433,3363,3289,
3213,3134,3051,2966,2878,2787,2694,2598,
2500,2399,2296,2191,2084,1975,1864,1751,
1636,1520,1403,1284,1164,1043, 921, 799,
675,551
All the game does with this table is add or subtract a bit of experience depending if it's Noa or Gala. First the calculation to get the amount to modify.
exp * 20 / stunt
So if Noa, subtract the amount. If Gala, add the amount. They're usually around a percent or so difference.
And there you have it. The not so easy way of doing experience tables. So when I had to dump out these experience tables, there was no way to just pull it out of the game