Home Gallery Resources The Team Rules chat Login Register
  Show Posts
Pages:  1 ... 5 6 7 [8] 9 10 11
106  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - PW is amazing! on: April 28, 2013, 11:50:51 AM
This looks cool. Would you be able to do that code for say characters? Samus and Zamus are characters that have notoriously strict memory limits and I think it would be amazing if there was a way to allocate at least 50 more kb than what Brawl has allocated for them.

Memory heaps are allocated by player as opposed to character. Each player has 4 memory heaps allocated to them. For player 1, they are:

[00553400] Fighter1Resource
[00087C00] Fighter1Resource2
[00052000] Fighter1Instance
[00048500] OverlayFighter1

Judging from the sizes, I would say Fighter1Resource is used for the model and Fighter1Resource2 is used for movesets and effects. Fighter1Instance is used specifically for the runtime character instance and I know that OverlayFighter1 is used for storing and executing the character's module.

As a side note, because there are only 4 fighter slots, alloys are stored collectively inside the Fighter3 and Fighter4 heaps - they can get away with this because they are smaller.

As far as increasing the size of these goes, we only have 510kb to work with - so if we were to distribute them over the 4 Resource2 heaps, it would only be an increase of about 128kb each.


I will try to see if it are any more articles we can port to other one. I bet all articles thats used by the Special B can be ported like luigis fireball, samus Charge Beam ect

The hardest part is finding the article ctor and dtor functions as well as the instantiation function. If you can find those 3 functions and the proper parameters to pass in when calling them, then porting them shouldn't be a problem.
107  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - PW is amazing! on: April 27, 2013, 08:47:09 PM
okay, I have looks everywhere of how you did Im srs here wanna port it to pal but I cant find how you did!

could you pm me of how you did and where you changed? cause it is just simply amazing!

if you have time and want that ofcourse!

The main areas I changed - in broad terms - are as follows:

0x5C20: Removed all but one call to Create_wnMarioFireball_holder_and_article
0x7B60: Changed Create_wnMarioFireball_holder_and_article to call wnRobotBeam.ctor instead of wnMarioFireball.ctor.
0x7BB4: Changed wnInstanceHolder<wnMarioFireball>.Method[0][0] to call wnRobotBeam.dtor instead of wnMarioFireball.dtor
0x7C10: Removed all but the first call to soInstanceHolder<wnMarioFireball>.Method[0][0]
0xAEA4: Changed wnArticleMediator.Method[0][1] to only check the first instance holder when creating an instance of wnRobotBeam
0xAFB0: Changed wnArticleMediator.Method[0][1] to call wnRobotBeam.instantiate instead of wnMarioFireball.instantiate
0xB3D0: Changed wnArticleMediator.Method[1][3] to only try to clear 1 wnRobotBeam instance.
0xB6E8: Changed wnArticleMediator.Method[1][4] to only check 1 wnRobotBeam instance holder.
0xB950: Changed wnArticleMediator.Method[1][5] to return an instance cap of 1 for wnRobotBeam
0xBD80: Changed wnArticleMediator.Method[1][2] to only clear 1 wnRobotBeam instance.

Just for reference, the method listing for wnArticleMediator is as follows:

Code:
soArticleMediator : soArticleGenerator, soArticleOperator

soArticleGenerator
Method[0][0] Finalizer
Method[0][1] GenerateArticle(r4=article_id, r5=soModuleAccessor)
soArticleOperator
Method[1][0] Method[0][0] Thunk
Method[1][1] Method[1][8] Thunk
Method[1][2] ClearInstances()
Method[1][3] ClearInstances(r4=soModuleAccessor, r5=Article_id)
Method[1][4] GetInstanceCount(r4=soModuleAccessor, r5=article_id)
Method[1][5] GetInstanceCap(r4=article_id)
Method[1][6] GetArticleCount()
Method[1][7] SetEnabled(r4=val)
Method[1][8] PSAEvent1001(r4=soModuleAccessor, r5=soArticle)



It seems like a lot, but the actual number of instructions I changed is probably no more than 20. If you compare the modified module to the original Mario module, you should be able to get a good idea of what needs to be changed in the PAL version.




Concerning the file size limits: I think I may have stumbled upon a code that can be used to increase the amount of memory allocated towards stage icons. Unfortunately Brawl makes almost full use of the Wii's memory, so there's not a lot of room for expansion. However, it seems that you can safely increase the limit by approximately 510kb without causing the game to run out of memory.

Anyone care to test this for me? You'll need a sc_selmap.pac file that exceeds the normal size limit.

Code:

MenuResource Expansion (+510kb)
04422384 006E6700


108  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - PW is amazing! on: April 26, 2013, 02:02:28 PM
I would imagine something like this would help with the bizarre Plug&Play .rels behavior in regards to costume slots. In case you weren't aware, I've found that if you port a character to another who has a FitChar## that the original does not, that costume can't be selected.

For me, I've got Roy over ROB and Mewtwo over Jiggs. Roy can't access FitRobot06, it loads FitRobot00 instead. Mewtwo can't get FitPurin03.


The Plug&Play modules cover color restrictions as well to prevent crashing in case one of the original's colors aren't covered by the new character's. If you want to remove the color restrictions on Marth's module, just change the flags at 0xE6 in Section[8] of Marth's module.

The flags are documented here under Costume Flags.

Just remember that you need to make sure that all interface elements including CSPs and battle portraits exist for the additional colors.
109  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - PW is amazing! on: April 25, 2013, 10:23:17 PM
Well, Rob's laser has been successfully ported over to Mario. It turns out I forgot to change the calls for wnMarioFireball.dtor to wnRobotLaser.dtor. There's also an oddity in the instantiation function which seems to use Mario's FLUDD charge time (viewable in BrawlBox) as a bone index for where the laser should be generated. As Mario's model doesn't contain a Bone 90, the game was crashing whenever it tried to create one.

Aside from that, Mario's Article1 parameters are now used as parameters for Rob's laser. The laser functions as it should including its ricochet behavior - however I still haven't found a way to allow Mario to aim it when shooting it. There is also a problem in that the laser uses Rob's laser effect meaning that if Rob isn't in the match, it will only appear a white polygon trail - I think BrawlBox's latest REFT editor should be able to fix that though.

I've learned a lot about articles and their constructors from this experiment. For the most part, articles are constructed almost identically aside from a few minor tweaks to the resulting object. Another interesting thing to note is that articles are also constructed nearly identically to actual characters - meaning it may be possible sometime in the future to use a character as an article.


I've also been experimenting a little bit with using menu_selchar.rel and menu_selchar_access.rel to implement the custom CSS code and include localized (and extendable) character color and icon options (think Brawl Masquerade) - but I think it would be better if I found a way to load a custom extension module file instead which all main game modifications can be pooled inside.




Anyways, here's the Laser Mario files. Right now you can only shoot one laser at a time because I only made one instance holder for it. Adding multiple instance holders - while possible - would take a substantial amount of manual hex editing that's not really necessary for the sake of this experiment.

I've also made a couple of cosmetic changes to the laser's behavior - that was mostly just for fun.

Laser Mario
110  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 24, Post #347 - Thank you, PW on: April 11, 2013, 05:54:22 PM
PW, can you comment more on the AI controllers you referred to here?
I have made a lot of progress on AI and that may be what I need to finish things off

I don't know a whole lot about them myself. They are stored in the middle of a vtable at 0x80B27A34. More specifically, they're stored at m1b[5] 0x48B94[/i] and happen to be positioned right beside a reference to the string "aiInput". Each one corresponds to a character id and gets called constantly during a match. Back with some of my earlier attempts at creating clone modules, they caused the game to crash for certain CPU clones when they were left unchanged. However, it also crashed when I was working with the Plug&Play modules and accidentally set the ptr to 0 even though I was a player at the time - so it seems they aren't exclusively called just for CPUs.
111  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - PW is amazing! on: April 11, 2013, 04:21:00 PM
okay! you just smash my head with a hammer! stop being so awesome and tell me what you did Im srs here

well, dont stop being awesome and share some information of how you did! that might help alot!

Well, the whole process was rather lengthily, but I'll try to break it down the best I can.

It all starts in your target character's ctor function. For my case, I used ftMario.ctor. ftMario.ctor is located at file offset 0x13C. In one of my earlier posts I discussed how ftCharacter.ctor is responsible for creating the whole character memory object as well as all the module objects associated with it. In particular, we are interested in soGenerateArticleManageModuleImpl which is responsible for generating and manipulating character articles (characters without any articles will not implement this modules). Most ftCharacter.ctor functions generally take the same shape. This means that for most module files, the part of ftCharacter.ctor that calls soGenerateArticleManageModuleImpl.ctor is usually around file offset 0x850. As it turns out, the constructor call for Mario's article module is located at file offset 0x838. Following this call we find out that the soGenerateArticleManageModuleImpl.ctor function is located at file offset 0x5A74 inside ft_mario.rel

Before I go into the soGenerateArticleManageModuleImpl.ctor function, I want to explain how the soGenerateArticleManageModuleImpl object is stored in memory. It is difficult to describe it using memory offsets, so I'll describe it as a basic C++ definition.

Code:

struct soGenerateArticleManageModuleImpl
{
    soArrayVector<wnArticle *, N> (size: 0xC + N * 0x4)
    soArrayVector<wnArticleEventObserver, N> (size: 0xC + N * 0x10)

    struct soArticleMediatorImpl
    {
         soInstancePool<...>
         soInstancePoolSub<...>[N]
    }
}


It may not make a whole lot of sense as it's just a definition, but try to keep it in mind when reading about the constructor function.



For Mario, the constructor function performs the following actions at the associated file offsets:

0x5A94 soArrayVector<wnArticle *, 5>.ctor(this)
0x5AA4 soArrayVector<wnArticleEventObserver, 5>.ctor(this + 0x20)
0x5AB4 [this + 0x7C] = soArticleMediatorImpl.declaration
0x5AA8 var soArticleMediator_ptr = this + 0x7C


Notice that the offsets 0x20 and 0x7C are equal to the summed sizes of the previous elements. That is:

0xC + 5 * 0x4 = 0x20
0xC + 5 * 0x10 = 0x5C

0x20 + 0x5C = 0x7C

This is important as you must make sure all you objects are not overlapping with other objects in memory when it comes to adding your own articles.

After these 3 base actions have been performed, there's two ways the function can go about creating articles. The first is the most basic; the constructor function does this starting at 0x5AC4:

0x5AC0 var soInstancePool<...>_ptr = this + 0x84
0x5ACC [this + 0x84] = soInstancePool<...>.declaration
// [this + 0x84] == [soArticleMediator_ptr + 0x8]

0x5AD8 [this + 0x88] = soInstancePoolSub<wnMarioHugeFlame, ...>.declaration
// [this + 0x88] == [soInstancePool<...>_ptr + 0x4]

0x5ADC var wnInstanceHolder<...>_ptr = soArticleMediator + 0xC
0x5AE8 [this + 0x90] = wnInstanceHolder<wnMarioHugeFlame, ...>.declaration
// [this + 0x90] == [wnInstanceHolder<...>_ptr + 0x00]

0x5B2C ftDataProvider.get_wnMarioHugeFlame_.pac_data(character_id = 0)
0x5B40 wnMarioHugeFlame.ctor(wnInstanceHolder<...>_ptr + 0x4, ...)

That's probably a lot of information to take in there, but suffice it to say, those 7 primary instructions are responsible for creating the wnMarioHugeFlame object - Mario's Final Smash. Whenever you want to create an article that only appears as a single instance onscreen, then this is the structure that gets used. Besides the offsets and function references, the structure mostly stays the same.

The second method for generating articles is used for articles that appear as multiple instances onscreen - such as Mario's fireballs. They get created starting at 0x5BBC:

// update the soInstancePool declaration with a new one containing the articles we're going to add.
0x5BC4 [this + 0x84] = soInstancePool<...>.declaration
0x5AC0 var temp = this + 0x20000
// [this + 0x84] == [soArticleMediator_ptr + 0x8]
// temp is used due to limitations in PowerPC's adding capabilities

0x5BD4 [temp - 0x5600] = soInstancePoolSub<wnMarioFireball, ...>.declaration
0x5BD8 var soInstancePools_ptr = temp - 0x5FFC
0x5BE4 [temp - 0x5FFC] = soInstancePoolSub<wnMarioFireball, ...>.declaration
0x5BF0 [temp - 0x5FF8] = soInstancePoolSub<wnMarioFireball, ...>.declaration
0x5C00 [temp - 0x5FF4] = soInstancePoolSub<wnMarioFireball, ...>.declaration
0x5C0C [temp - 0x5FF0] = soInstancePoolSub<wnMarioFireball, ...>.declaration
// These are written immediately following the previously created article.

0x5C18 Create_wnMarioFireball_holder_and_article(soInstancePools + 0xC, ...)
0x5C24 Create_wnMarioFireball_holder_and_article(soInstancePools + 0x1F54, ...)
0x5C30 Create_wnMarioFireball_holder_and_article(soInstancePools + 0x3EA4, ...)
0x5C3C Create_wnMarioFireball_holder_and_article(soInstancePools + 0x5DEC, ...)
0x5C48 Create_wnMarioFireball_holder_and_article(temp + 0x2738, ...)
// Once again, these offsets are immediately following the soInstancePoolSubs we just created.


The Create_wnMarioFireball_holder_and_article is another function inside ft_mario.rel - it can be found at file offset 0x7AF4. The function does exactly what it says.



So to summarize, the first method for creating articles has you updating the instance pool; creating the instance pool sub and instance holder; obtaining the .pac data; and creating the article all in the main function. The second method involves updating the instance pool, creating the instance pool subs and then calling the helper function to actually create the instance holder, obtain the .pac data, and create the article.



When it came to me adding ROB's laser, I replaced Create_wnMarioFireball_holder_and_article's wnMarioFireball.ctor and ftDataProvider.get_wnMarioFireball_.pac_data calls with calls to wnRobotBeam.ctor and ftDataProvider.get_wnRobotBeam_.pac_data. This wasn't a problem because both articles are Kirby-Copy articles meaning these functions were stored in sora_melee. When replacing the get .pac data function, it is also necessary to change the id being passed to it (or you can leave Mario's get .pac data function and end up with a weird mixture of both of them like I mentioned above).

I should also mention that the actual wnInstanceHolder and soInstancePoolSub declarations don't need to be changed as they are just primitive data structures that all have exactly the same shape and functionality.

Additionally, I removed all but the first call to Create_wnMarioFireball_holder_and_article as wnRobotBeam is actually larger in size than wnMarioFireball and - like I said ealier - you can't have objects overlapping in memory (you can find the size of wnMarioFireball by subtracting the offsets that are passed to Create_wnMarioFireball_holder_and_article).

Finally, I had to change the article count references and the call to ftMarioTransactor.instantiate_wnMarioFireball located inside soArticleMediatorImpl. If these count values weren't changed, then the game will crash by trying to access the other 4 article instances which I removed.

I've listed the basic details on that in one of my earlier posts, but to find everything you'll need to know the function listing of soArticleMediatorImpl:

Code:
soArticleMediator : soArticleGenerator, soArticleOperator

soArticleGenerator
Method[0][0] Finalizer
Method[0][1] GenerateArticle(r4=id, r5=soModuleAccessor)
soArticleOperator
Method[1][0] Method[0][0] Thunk
Method[1][1] Method[1][8] Thunk
Method[1][2] ClearInstances()
Method[1][3] ClearInstances(r4=soModuleAccessor, r5=id)
Method[1][4] GetInstanceCount(r4=soModuleAccessor, r5=id)
Method[1][5] GetInstanceCap(r4=id)
Method[1][6] GetArticleCount()
Method[1][7] SetEnabled(r4=val)
Method[1][8] PSA_Event_1001(r4=soModuleAccessor, r5=soArticle)




A lot of this was trial and error and there isn't really a consistent way of finding everything. Even after doing all that, there were still a couple of bugs which I had to resolve using WiiRD - and I'm not even sure what exactly was causing it.

Anyways, make of it what you will. Hopefully you'll be able to work something out with it. Like I said before: it's pretty complicated.


... Long post is long.
112  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 24, Post #347 - Thank you, PW on: April 11, 2013, 02:11:47 PM
Well it looks like porting Snake was a lot harder than I thought it would be. In the end, I updated the Plug&Play model to v1.2 to cover a certain oddity in sora_melee that made it difficult to patch entry data. There's not too many changes except for a new _prolog function that gets called before the v1.1 function. If anyone's had any problems porting characters over Fox, Falco, Peach, Wario, Metaknight or Snake, then this would be the cause for it.

The 3 new modules are Mario, Sonic and Snake

Plug&Play Modules v1.2:
ft_mario.rel
ft_link.rel
ft_marth.rel
ft_pit.rel
ft_lucario.rel
ft_ike.rel
ft_snake.rel
ft_sonic.rel


While cloning characters to completely new slots is technically possible using the Plug&Play modules, you still need to have interface elements, CSPs, and CSS icons for the new character slot. You also need to add a new .rel and .pac file paths to sora_melee so they get loaded according to the new character Id. Because the .rel can't actually patch it's own file string, you'll have to use codes. Perhaps a creative individual could come up with a patch function that executes on sora_menu_selchar_access.rel or some other modules which makes the appropriate changes when it is loaded.


One other thing to note, while CPUs no longer exhibit behavior dictated by the A.I. controller functions (such as Olimar's constant Neutral B usage) they do still seem to exhibit some behavior of the original characters such as when they use their FS. The only A.I. related data I know of are the A.I. controllers and the A.I. files inside the MotionEtc files so I'm not sure what needs to be patched to fixed this.



I think I'm going to take a break from hacking after this. I've done a pretty hefty hacking marathon this week and have neglected a lot of important things thanks to that. But we have made a lot of progress here.
113  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - Almost Perfect Spring on: April 09, 2013, 11:38:21 PM
Well, well, what have we here?



Now before the hype bandwagon gets kicked into high gear, there's a couple of things to note:


This is a very unstable test - a lot of what you see in the screenshot is the result of heavy modification of the game while it was running. The game also crashes when you exit the match.

Rob must be in the match to have the laser effect.

It is possible to load up Mario's fireball effect in place of the laser effect; this results in an odd merge between both articles. Mario shoots out a projectile that travels horizontally like a laser, but has the speed, hit effect, and damage of a fireball.

The laser was easy to copy into Mario's article bank because wnRobotLaser.ctor and ftRobotTransactor.instantiate_robot_laser are both stored as global functions in sora_melee due to Rob's laser being copyable by Kirby. Other articles are harder to replicate as their primary functions are stored inside the owner character's module file.




However, progress is progress, so I thought I'd report on it here. Here's hoping we can use this to generate more sophisticated custom characters.
114  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 24, Post #347 - Thank you, PW on: April 09, 2013, 08:10:41 PM
Section[8] is pretty simple. The primary components are the character Id, copy info and copy data.

It goes without saying that the character Id is stored in the first word of the section.

Starting at 0x20, the copy info is stored as entries in sequence. Each entry is 0x10 in size:

Copy Entry:
0x00 (ptr) destination
0x04 (ptr) source
0x08 (half) id_step
0x0A (half) data_size
0x0C (word) data_tag

Most of the fields are pretty self explanatory except id_step which simply offsets the destination address by character_id * id_step. The data_tag is 0xD8A for all entries except for the last one.

The last entry has a data_tag of 0x1D8A. This entry patches the character_id into the addresses stored at the source ptr. Writes are done in halfwords, so all addresses need to be shifted by 2 if you are writing to assembly addresses.

The first 9 copy entries are usually dedicated for patching known character parameters in sora_melee. The one's that will probably be the most useful are entries 7 and 8 which patch the character's soundbank and constants. Following the first 9 entries are the entries used for patching sora_melee functions.



Finding the functions in sora_melee is no easy feat. The main places where cloned characters will encounter errors in sora_melee are the places where the game reuses code for other characters. This is primarily to do with places involving Kirby's copy abilities, but there are other places like in the case of Link's Final Smash which has code shared with ToonLink's Final Smash.

For Snake, there shouldn't be too many problems because the grenades are of type wnSimple (I think...) which means that there shouldn't be any special code sharing to allow Kirby to use them.

As for the remaining articles, as long as you patch all the constant character Id values in ft_snake.rel, they shouldn't exhibit any problems.
115  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 24, Post #347 - Thank you, PW on: April 09, 2013, 02:17:26 PM
You don't need any codes for entries as those are also covered by the modules.

I've tested Lucario over Yoshi and it works with no problems. I haven't tested Mewtwo yet though. I suggest that you first get Lucario working over Yoshi, and then replace Lucario's files with Mewtwo's like usual.
116  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 20, Post #288 - on: April 07, 2013, 09:44:17 PM
More Plug&Play modules:

Plug&Play Modules v1.1:
ft_link
ft_marth
ft_pit
ft_ike
ft_lucario

(Credit to Dantarion for his documentation of the modules on OpenSA.com)

I've also made a new revision to the Plug&Play model. Most of it was just to make the modules a bit easier to deal with on my end, but the new modules also now cover any bugs related to entry and result screen files as well as a few other character related flags. I've also disabled Kirby Hats for all cloned characters to avoid possible complications involving character resources (They can still be enabled, but you get the original character's hat).

As far as I've tested, all 5 of these modules work perfectly in game (Including Lucario, who's Aura Sphere now properly shows up). However, the bugs concerning when graphical and sound files get loaded and unloaded still remains. Also, while the modules do patch the soundbanks, the soundbanks actually get read before the module is loaded - so the first time you load them, they won't have the proper soundbank loaded.

I've also added a small tweak to the Module Editor 3 to make it easier to change the modules between characters.

Module Editor v3.2

To change a module, simply open it up in the editor and make the following changes:

- Change the module Id of the file to the target module Id.
- Open Section[8] in the memory viewer and change the first value to the target character Id.

The list of module and character Ids is here:


Code:
Module Ids:
5B ft_mario
5C ft_donkey
5D ft_link
5E ft_samus
5F ft_yoshi
60 ft_kirby
61 ft_fox
62 ft_pikachu
63 ft_luigi
64 ft_captain
65 ft_ness
66 ft_koopa
67 ft_peach
68 ft_zelda
69 ft_iceclimber
6A ft_marth
6B ft_gamewatch
6C ft_falco
6D ft_ganon
6E ft_wario
6F ft_metaknight
70 ft_pit
71 ft_pikmin
72 ft_lucas
73 ft_diddy
74 ft_poke
75 ft_dedede
76 ft_lucario
77 ft_ike
78 ft_robot
79 ft_toonlink
7A ft_snake
7B ft_sonic
7C ft_purin
7D ft_wolf
7E ft_zako




Character Ids:
00 Mario
01 Donkey Kong
02 Link
03 Samus
04 Yoshi
05 Kirby
06 Fox
07 Pikachu
08 Luigi
09 Captain Falcon
0A Ness
0B Bowser
0C Peach
0D Zelda
0E Sheik
0F Popo
10 (Nana)
11 Marth
12 Mr. Game & Watch
13 Falco
14 Ganondorf
15 Wario
16 Metaknight
17 Pit
18 Zero Suit Samus
19 Olimar
1A Lucas
1B Diddy Kong
1C Pokemon Trainer
1D Charizard
1E Squirtle
1F Ivysaur
20 Dedede
21 Lucario
22 Ike
23 Robot
24 (Pra-mai)
25 Jigglypuff
26 (Mewtwo)
27 (Roy)
28 (Dr. Mario)
29 Toon Link
2A (Toon Zelda)
2B (Toon Sheik)
2C Wolf
2D (Dixie)
2E Snake
2F Sonic
30 Giga Bowser
31 Warioman
32 Red Alloy
33 Blue Alloy
34 Yellow Alloy
35 Green Alloy
36 (Mario D)




As far as how these modules work: simply put, they are just doing the same thing that codes do, but they make things a whole lot simpler by exploiting the powerful nature of relocations as well as the fact that modules are programs that can be run when they're loaded up.

For each module, I've added a simple program in Section[7] that gets called first during the module's _prolog function. Section[7] is identical across all of the Plug&Play modules. The actual changes and associated data are stored in Section[8] of the module. These are hex strings that are used to patch the game files when the module is loaded; this includes things like constants and color flags as well as any changes that need to be made to sora_melee. One final block in Section[8] is responsible for identifying what changes need to be made inside the module itself in order for it to function properly.

It's really quite a simple, but elegant solution to the whole mess of dealing with modules and how they integrate with sora_melee along with other global data. Making them isn't that hard - it's just tedious given the tools currently available to edit modules. The hardest part is finding the areas in sora_melee that actually need to be patched to have the cloned characters run properly.
117  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Check Page 20, Post #288 - on: March 31, 2013, 12:57:31 AM
Alright, it looks like the research on modules that began all those years ago has finally yielded some results.

This new line of modules which I've dubbed Plug&Play modules requires no codes for constants, no codes for A.I. controllers and no changes to sora_melee. These modules will work with or without the original character in the match. Moreover, customizing the module for each character slot is a matter of changing 3 values inside the file. Of course, you still need the actual moveset and motion files to go along with the module, but those files can be used as-is without any changes.

Right now, I've only created one of this kind of module: ft_Lucario.rel which me and SonicBrawler were working on - feel free to try it out. The changes needed turn turn it into a Lucario clone over any other character are documented in the .txt that's with the file.

ft_lucario Plug&Play v1.0.rel

I should note that the original bug where Lucario's Aura Sphere is not visible is still there. Also, if you load two Lucario characters and then unload one of them, it will unload Lucario's aura graphic effects along with it leaving the remaining one without any effects. Both of these bugs seem to be beyond the scope of the modules and are directly related to effect files and how they're indexed.

The module has been tested over Mario, Pit, Marth and Rob and performed consistently across the four of them, but it hasn't been tested on the entire roster.

One final note: while there was mention of using the Project M codes to aid in the development of a working Lucario clone, I have not taken the time to examine or reverse engineer the Project M codes. This module was a product of my own work.
118  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - Almost Perfect Spring on: January 18, 2013, 04:18:20 PM
Yeah, sorry about the Module Editor 2.2. Unfortunately, I programmed it really poorly, so adding a function to view the whole assembly block is really more trouble than it's worth. Instead, I've been using the first version of the module editor whenever it comes to viewing standalone functions (I actually use all 3 versions for different purposes XD). Now that BlackJax has started to implement the assembly viewer in BrawlBox, I don't think continuing to work on the Module Viewer is really worth it anymore.

Anyways, here's the v1 download in case you need it:

Module Editor v1
119  Super Smash Bros. Brawl Hacking / Programming / Re: Perfect .Rel porting Progress -Video added to OP- on: January 16, 2013, 11:48:42 PM
I've posted some info over in the module file thread which may be useful when it comes to cloning modules.

Just remember that while it does add a lot of clarity into the cloning process, most of the points I mentioned are ones that you guys are already changing when porting modules - so it may not be able to help much in terms of progress.
120  Super Smash Bros. Brawl Hacking / Programming / Re: Let's look into Module Fíles (.rel) - Almost Perfect Spring on: January 16, 2013, 11:42:00 PM
Alright, Info Dump time!

It looks like modules aren't so chaotically structured after all. There's actually quite a bit of coherence to them if you know where to look.

First of all, here's a mapping of some of the more important functions in ftLucario.rel:

("ctor" is short for "constructor")

0xCC BSSList.add(r3=obj, r4=finalizer, r5=new_node)
0xD8 BSSList.clear() (this is actually module finalizer[0])
0x13C ftLucario.ctor(r4=?, r5=?, r6=?, r7=?)

0xD388 ftLucarioExtendParamAccesser.ctor()
0xD3D0 ftClassInfoImpl.ctor()

0x11928 wnLucarioQigong.ctor(r4=?, r5=stack_data, r6=.pac_resource)
0x9B18 create_wnLucarioQigong_instance(r4=?)

0x8ECC init_ftLucarioTransactor()

Module Constructors:
0x712C soResourceModuleImpl.ctor(r4=owner, r5=?, r6=?, r7=soModuleAccessor)
0x7194 soModelModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
0x721C soMotionModuleImpl.ctor(r4=soModuleAccessor, r5=?)
0x73F0 soPostureModuleImpl.ctor(r4=soModuleAccessor, r5=?)
0x7460 soGroundModuleImpl.ctor(r4=soModuleAccessor)
[BASE] soSituationModuleImpl.ctor
0x6D0C soTeamModuleImpl.ctor(r4=?, r5=soModuleAccessor)
0x74C4 soCollisionAttackModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?)
0x7588 soCollisionHitModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?)
0x764C soCollisionShieldModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
0x7720 soCollisionShieldModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
[NULL] soCollisionShieldModuleNull
0x77F4 soCollisionCatchModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
[NULL] soCollisionSearchModuleNull
0x788C soDamageModuleActor.ctor(r4=soModuleAccessor, r5=?)
[BASE] soCatchModuleImpl.ctor
[BASE] soCaptureModuleImpl.ctor
[BASE] ftStopModuleImpl.ctor
[BASE] soTurnModuleImpl.ctor
0x78F8 soShakeModuleImpl.ctor(r4=soModuleAccessor, r5=?)
0x7954 soSoundModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
0x79E4 soLinkModuleImpl.ctor(r4=soModuleAccessor)
[BASE] soVisibilityModuleImpl.ctor
0x7A38 ftControllerModuleImpl.ctor(r4=soModuleAccessor, r5=?)
0x7AA8 soCameraModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?)
[BASE] soWorkManageModuleImpl.ctor
[NULL] soDebugModuleNull
0x7B14 soAnimCmdModuleImpl.ctor(r4=?)
0x7B58 soStatusModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
[NULL] ftGeneralTermDisideModuleNull
[NULL] ftSwitchDecideModuleNull
0x8010 soKineticModuleGenericImpl.ctor(r4=soModuleAccessor)
[BASE] soEventManageModuleImpl.ctor
0x8440 soGenerateArticleManageModuleImpl.ctor(r4=soModuleAccessor)
0x863C soEffectModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?, r8=?, r9=?)
[BASE] ftComboModuleImpl.ctor
0x8708 ftAreaModuleImpl.ctor(r4=soModuleAccessor, r5=?, r6=?)
[NULL] soTerritoryModuleNull
[NULL] soTargetSearchModuleNull
0x87A0 soPhysicsModuleImpl.ctor(r4=soModuleAccessor, r5=?)
[BASE] soSlopeModuleImpl.ctor
[BASE] soShadowModuleImpl.ctor
0x8800 soItemManageModuleImpl.ctor(r4=soModuleAccessor, r5=?)
[BASE] soColorBlendModuleImpl.ctor
[BASE] soJostleModuleImpl.ctor
[BASE] ftAbnormalModuleImpl.ctor
[BASE] soSlowModuleImpl.ctor
[NULL] soReflectModuleNull
[BASE] soHeapModuleImpl.ctor
0xD67C ftLucarioParamCustomizeModule.ctor(r4=?)
[BASE] ftGlowModuleImpl.ctor

Next, here's a mapping for a few constructor functions in sora_melee.


0x1257EC Fighter.base_ctor(r4=?, r5=id, r6=?, r7=?)

0x192D4C ftFighterBuildData.base_ctor(r4=?, r5=id, r6=?, r7=?, r8=?, r9=?)

0xD8E28 soInstanceManagerFixedSimple.base_ctor()

0x68598 soModuleAccessor.base_ctor(r4=owner, r5-r10=modules, r1=modules)

0x6F850 soResourceModuleImpl.base_ctor(r4=?, r5=?, r6=?)
0x77DC soModelModuleImpl.base_ctor(r4-r8=?)
0x13844 soMotionModuleImpl.base_ctor(r4=soModuleAccessor, r5=?)
0x23364 soPostureModuleImpl.base_ctor(r4=soModuleAccessor, r5=?)
0x2556C soGroundModuleImpl.base_ctor(r4=soModuleAccessor)
0x3513C soSituationModuleImpl.base_ctor(r4=?, r5=soModuleAccessor, r6=?)
0xB5048 soTeamModuleImpl.base_ctor(r4-r8=?)
0x39590 soCollisionAttackModuleImpl.base_ctor(r4-r10=?)
0x42AA4 soCollisionHitModuleImpl.base_ctor(r4-r10=?)
0x48A1C soCollisionShieldModuleImpl.base_ctor(r4-r10=?)
0x48A1C soCollisionShieldModuleImpl.base_ctor(r4-r10=?)
[NULL] soCollisionShieldModuleNull
0x4B184 soCollisionCatchModuleImpl.base_ctor(r4-r10=?)
[NULL] soCollisionSearchModuleNull
0x61454 soDamageModuleActor.base_ctor(r4-r8=?)
0x64C8C soCatchModuleImpl.base_ctor(r4=soModuleAccessor, r5=?)
0x65EE4 soCaptureModuleImpl.base_ctor(r4=soModuleAccessor)
0x154088 ftStopModuleImpl.base_ctor(r4=soModuleAccessor)
0x693F4 soTurnModuleImpl.base_ctor(r4=soModuleAccessor)
0x68888 soShakeModuleImpl.base_ctor(r4=?, r5=?, r6=?)
0x561E0 soSoundModuleImpl.base_ctor(r4-r9=?)
0x6A244 soLinkModuleImpl.base_ctor(r4=?, r5=?)
0x5B248 soVisibilityModuleImpl.base_ctor(r4=soModuleAccessor, r5=?, r6=?)
0x150320 ftControllerModuleImpl.base_ctor(r4-r7=?)
0xB215C soCameraModuleImpl.base_ctor(r4-r8=?)
0xA1DA4 soWorkManageModuleImpl.base_ctor(r4=soModuleAccessor, r5=?)
[NULL] soDebugModuleNull
0x1AB96C soAnimCmdModuleImpl.base_ctor(r4=?)
0x73930 soStatusModuleImpl.base_ctor(r4-r10=?)
[NULL] ftGeneralTermDisideModuleNull
[NULL] ftSwitchDecideModuleImplNull
0xB6DBC soKineticModuleGenericImpl.base_ctor(r4=?, r5=?, r6=?)
0x8EBF0 soEventManageModuleImpl.base_ctor(r4=owner)
0x92F10 soGenerateArticleManageModuleImpl.base_ctor(r4-r7=?)
0x9747C soEffectModuleImpl.base_ctor(r4-r10=?)
0x14FBD8 ftComboModuleImpl.base_ctor(r4=soModuleAccessor)
0x14DFE4 ftAreaModuleImpl.base_ctor(r4-r10=?)
[NULL] soTerritoryModuleNull
[NULL] soTargetSearchModuleNull
0x10158 soPhysicsModuleImpl.base_ctor(r4-r7=?)
0xACAC4 soSlopeModuleImpl.base_ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?)
0xB62E4 soShadowModuleImpl.base_ctor(r4=soModuleAccessor, r5=?, f1=?)
0xB7E20 ItemManageModuleImpl.base_ctor(r4-r9=?)
0xBEBB4 soColorBlendModuleImpl.base_ctor(r4=soModuleAccessor, r5=?, r6=?)
0xC20D8 soJostleModuleImpl.base_ctor(r4=soModuleAccessor, r5=?, r6=?, r7=?)
0x196664 ftAbnormalModuleImpl.base_ctor(r4=soModuleAccessor)
0x5BED0 soSlowModuleImpl.base_ctor(r4=soModuleAccessor)
[NULL] soReflectModuleNull
0x649FC soHeapModuleImpl.base_ctor(r4=?, r5=?, r6=?, r7=?)
0x14B5F8 ftParamCustomizeModuleImpl.base_ctor(r4=?)
0x14CCEC ftGlowModuleImpl.base_ctor(r4=soModuleAccessor)

Finally a few more functions which are relevant to Lucario in the sora_melee module:


0x39BDA8 wnLucarioAuraBall.ctor(r4=?, r5=stack_data, r6=.pac_resource)
0x39B0A8 create_wnLucarioAuraBall_instance(r4=?, r5=?)

0x39A924 ftLucarioTransactor.ctor()


So what is the significance of all this? Well, I'll try to explain it the best I can.



All interfacing with the character modules are primarily done through the ftClassInfoImpl objects. In particular, whenever the game needs an instance of Lucario, it calls ftClassInfoImpl<33, ftLucario>.Method[0][2]. This function simply calls ftLucario.ctor.

ftLucario.ctor calls Fighter.base_ctor, ftFighterBuildData.base_ctor, soInstanceManagerFixedSimple.base_ctor, soModuleAccessor.base_ctor and each of the module constructors. Most character modules will usually create derived versions of the modules so they will implement their own constructors which will generate part of the object and then call the sora_melee version of the constructor. Sometimes though the character module will instead just opt to call the base constructor on its own as all it needs is the base functionality of the sora_melee version. Other times, a null placeholder will be loaded up in place of the module instead.

I haven't mapped all the functions that ftLucario.ctor calls yet, but that much on its own is pretty interesting.

Of particular interest is the soGenerateArticleManageModuleImpl.ctor function. Characters who don't use articles will fill the soGenerateArticleManageModuleImpl spot with a null placeholder, but characters who do use articles will have this function implemented. In addition to creating the base soGenerateArticleManageModuleImpl object, the implemented constructor will also create create soInstancePool, soInstancePoolSub and wnInstanceHolder objects inside of the soGenerateArticleManageModuleImpl object. Additionally, it will also call the constructor functions for the articles (in Lucario's case, it calls wnLucarioQigong.ctor and wnLucarioAuraBall.ctor). Essentially, this function sets up all of Lucario's articles for use. Later on when we want to create instances of the articles, we call soArticleMediatorImpl.Method[0][1] which in turn calls either create_wnLucarioQigong_instance or create_wnLucarioAuraBall_instance.

On a side note, the reason the wnLucarioAuraBall constructor and instance generator functions are in sora_melee is because Kirby can copy Lucario's AuraBall.


There are other points of interest to this information too. When cloning modules, the places that cause difficulties in the cloning process are mainly the article constructors. Both wnLucarioQigong.ctor and wnLucarioAuraBall.ctor require a .pac_resource pointer. Cloned modules will usually try to retrieve the original's .pac_resource pointer which causes a crash if the original isn't loaded. Lucario's create_wnAuraBall_instance function also references a .pac_resource pointer. The ftLucarioExtendParamAccessor.ctor and ftClassInfoImpl<33, ftLucario>.ctor functions both statically reference the module id - both need to be changed when cloning. Fighter.base_ctor and ftFighterBuildData.base_ctor also reference the module id - when they are called in ftLucario.ctor, the passed id needs to be changed.

Finally, there some spots here and there which needs to gain access to the ftClassInfoImpl object. this is usually done by calling a specific sora_melee function and passing in the module id. One of the places that needs to call this function is near the end of ftLucario.ctor (this is the same for all characters). For Lucario's module, there are two other places which does this: ftLucario.Method[17][16] and ftLucario.Method[0][3]. I'm not sure the significance of these two functions, but their use doesn't seem to be universal.



Anyways, I think this information will prove useful not just for cloning characters, but for adding additional functionality to existing characters as well. Unfortunately, there seems to be a lot of syntax to follow in order to ensure things run nicely - but hopefully that will come with time.
Pages:  1 ... 5 6 7 [8] 9 10 11