More on adding articles:
Our goal is fairly simple. In order to add more articles to a character, we need to expand the memory stored in the character's soGenerateArticleManageModule. Normally, this would be difficult as simply increasing its size would end up overwriting any module that comes after it. However, we can avoid this issue by adding additional memory to end of the character's allocated memory space and then moving the resized soGenerateArticleManageModule to the new space.
The first step - increasing the character's allocated memory - is easy. The character's size is simply a constant stored in Method[0][2] of the character's ftClassInfoImpl:
Here, the 0x8000C8B8 function call is equivalent to the C-style malloc call. The argument r3 specifies the size in bytes while the r4 argument specifies which heap to allocate the memory on. The highlighted instructions load r3 with 0x10548 - the size of the ftLucario object in memory.
Next, we need to change the ftLucario constructor so that the soGenerateArticleManageModule is created in the new location. Immediately following the malloc call above, is the function call into the the ftLucario constructor. It takes a while to learn the layout of character constructors, but once you do, it becomes fairly easy to find the location where the different module constructors get called. In this case, Lucario's soGenerateArticleManageModule constructor gets called at section[1]+0x75C.
Register r25 actually points to the soInstanceManagerFixedSimple shown in the top image. 0x5C24 is the offset inside of it where soGenerateArticleManageModule gets created. The function call with offset 0x8374 is the constructor for soGenerateArticleManageModule. Moving back up a ways, we can find out what value r25 gets set to:
Here, r24 points to the beginning of the ftLucario object - the pointer we got back from our malloc call. The offset 0x194 is the position inside ftLucario where soInstanceManagerFixedSimple is stored. As a result, in order to move the soGenerateArticleManageModule to the end of the ftLucario memory, we need change the soGenerateArticleManageModule constructor offset value to:
offset = <original ftLucario size> - <instance manager offset> = 0x103B4
Or equivalently, at section[1]+0x75C we need to change
addi r3, r25, 5C24
to
addis r3, r25, 0x0001
addi r3, r3, 0x03B4
This presents a problem as we now need to replace 1 assembly instruction with 2. However, this problem can be solved fairly easily using a hook function that performs the operations needed elsewhere. Looking at the 8 Aura Sphere module you can find an example of this procedure, but I'm not going to go into much more details on the topic besides that.
Now that we have moved the soGenerateArticleManageModule, there are 3 other places where we need to change similar pointers so the new location can be properly accessed. Those 3 places are: the soModuleAccessor reference, the soGenerateArticleManageModule destructor, and the soGenerateArticleManageModule base destructor. The destructors are pretty easy to deal with as the game will crash very close to the point where they are called if their pointers aren't updated. From the crash, you can easily use the Dolphin debugger to trace back to where each pointer gets loaded.
As for the soModuleAccessor pointer, it can be found in the ftLucario constructor as well.
Note that the offset loaded here, (soInstanceManagerFixedSimple + 0xDC04) is not the same as the offset used to create the soGenerateArticleManageModule (soInstanceManagerFixedSimple + 0x5C24). This is because we are actually pointing at the soGenerateArticleManageModule base class which is stored inside the implemented version of the module. We aren't going to change this one yet, as the internal offset of the base class will change once we increase the size of the soGenerateArticleManageModule. However, if you did change this pointer - along with the other ones discussed so far, you could load this modified ftLucario.rel into the game and it would run perfectly fine with the new soGenerateArticleManageModule location.
That being said, we are only half way done. We still need to increase the size of the soGenerateArticleManageModule, add new wnInstanceHolder objects to store the new articles, and refactor the soGenerateArticleManageModule's assembly to work with the new memory layout.
Please stand by as I take a lunch break. We will resume later this evening