Homebrew [WIP] PHBank - Pokémon Homebrew Bank

the assaf

Well-Known Member
Member
Joined
Jun 2, 2013
Messages
489
Trophies
0
Age
29
XP
360
Country
I noticed the .smdh had some corrupted characters on where the é goes. Here is a screenshot. I tested with other smdh editors just to make sure it was not the font from the homebrew launcher mod.

746sghm.png
Attached I'll leave a fixed version.:)
This is caused by hbl lack of characters, also official smdh for oras special demo have the same issue.
 

Gocario

GBAFail'd
OP
Member
Joined
Sep 5, 2015
Messages
640
Trophies
0
Location
Bourg Palette
XP
804
Country
France
Well, there goes my 721 bytes array :P, glad I used some search and replace from the bulbapedia page and got it in 5 minutes, and not manually typed it.
Glad to know you like the multiple bank idea, that would content those asking for more boxes.
Yes, I forgot hoopa is already released, the unbankable one is volcanion only I think, but I'll test.

About region updating, I'm gonna make some tests to find out that. HT data doesn't store any identifier for him, so my guess is that region is not updated if new region is the same as latest region (slot 1), since the pokemon is in the same region.
That is what I did! :c
I won't implement the multi-bank now, tho.

The region is always updated in normal trades: http://puu.sh/kDMIi/3d5e8a0468.png.

And, what about the eggs... ?
Can we stored them? If not shall we allowed it?
 

suloku

Well-Known Member
Member
Joined
Apr 28, 2008
Messages
883
Trophies
0
XP
866
Country
That is what I did! :c
I won't implement the multi-bank now, tho.

The region is always updated in normal trades: http://puu.sh/kDMIi/3d5e8a0468.png.

And, what about the eggs... ?
Can we stored them? If not shall we allowed it?

I'm testing the region thing, I did what you posted and region was NOT updated the second time, only slot 1 is set. I'll try with a third same region save. I also tested OT drop in bank, exit, then retrieve with OT and no data was changed for the pokemon (as expected).

OT deposits in bank
HT 1 withdraws --> region slot 1 is set
HT 1 deposists in bank
HT 2 withdraws --> what will happen?

UPDATE: that sets another region slot, just like normal. Further tests needed, I think it just checks trainer name and region, but now I want to know this:
HT 1 withdraws --> region slot 1 is set
HT 1 deposists in bank
HT 1 withdraws --> are the memories reset again?

I've checked and seems they are not! I'll test with friendship, see if it resets (in my tests they had base friendship). So, how does the bank know that notOT was the last one that deposited it in the bank?
I'd say the bank saves at least TID+SID+Tname (from trainer that left it in the bank) + pk6 for each pokemon. Maybe it uses full trainer info with even region, I'll need to test with that too...

About eggs: I've just read that regular bank does NOT allow them to be deposited. I don't have any right now, but I will test with an actual egg since maybe a bank update changed that.

I don't see the reason behind the bank not allowing egg storage, Pokemon Box for gamecube allowed them.
The fact that there's no way to know what the egg is may be the cause.
Since eggs can be normally traded, I'd say it could be allowed with no problem whatsoever. OT is set to that of the hatcher, and memory data, location data, etc is set after they hatch, so the memory update whould be not performed for eggs (if allowed), they should be just plain copy-paste of the data.

You could put an option in the menu to allow eggs; if that option is disabled by default your release will replicate pokemon bank behavior, it would be up to the user to use that enhanced feature.
 
Last edited by suloku,

shinyquagsire23

SALT/Sm4sh Leak Guy
Member
Joined
Nov 18, 2012
Messages
1,977
Trophies
2
Age
26
Location
Las Vegas
XP
3,765
Country
United States
So I just made a PoC for reading from a cart/digital game's romFS on my Github at https://github.com/shinyquagsire23/nh2-cart-romfs. It's fairly basic and the example will print a small header from Pokemon X/Y/ORAS (should be CRAG). But using this you could totally read out icons and image data from the games themselves if you're interested. Even if you aren't I'll probably give it a go once I get the chance to. There's romFS printouts for XY at http://pastebin.com/QNCz7Avh and ORAS at http://pastebin.com/4bg3q6FL.
 
Last edited by shinyquagsire23,
  • Like
Reactions: Margen67

Gocario

GBAFail'd
OP
Member
Joined
Sep 5, 2015
Messages
640
Trophies
0
Location
Bourg Palette
XP
804
Country
France
So I just made a PoC for reading from a cart/digital game's romFS on my Github at https://github.com/shinyquagsire23/nh2-cart-romfs. It's fairly basic and the example will print a small header from Pokemon X/Y/ORAS (should be CRAG). But using this you could totally read out icons and image data from the games themselves if you're interested. Even if you aren't I'll probably give it a go once I get the chance to. There's romFS printouts for XY at http://pastebin.com/QNCz7Avh and ORAS at http://pastebin.com/4bg3q6FL.
It sounds hard for someone like me... :c

If I understand correctly it reads file in folder in folder in folder? Or is it more abstract?

OR/AS:
  • a/0/9/1 - 971 box sprites
  • a/1/0/3 - Box name/wallpaper UI

PS: I can't compile (I'm using windows)
upload_2015-10-9_11-47-3.png
 
  • Like
Reactions: Margen67

shinyquagsire23

SALT/Sm4sh Leak Guy
Member
Joined
Nov 18, 2012
Messages
1,977
Trophies
2
Age
26
Location
Las Vegas
XP
3,765
Country
United States
It sounds hard for someone like me... :c

If I understand correctly it reads file in folder in folder in folder? Or is it more abstract?



PS: I can't compile (I'm using windows)
View attachment 26624
Oh, it seems your 3dsxtool is out of date. I don't use the 3dsx romfs anyways so you can remove these lines. And yes, it's literally a file named '1' under a/0/9/ for ORAS, I'm not 100% certain on the file formats though. They all seem to be "CRAG" containers with data in them. So you can fopen("romfs:/a/0/9/1") and do your thing, maybe dump the files you're going to look into interpreting. bclim2png is apparently what you'd use to convert it from a PC standpoint, but you'd probably want to see how to get a bclim to raw RGB data you can render.

EDIT: They're GARC archives, look into GARCTool to get at the files inside the archives and then find a way to use the bclims inside the GARC

EDIT 2: The bclims for Pokemon sprites are 40x30 RGBA5551 images, you could possibly just scan for CLIM headers if you don't want to implement GARCs but it would end up skipping the first image since the CLIM header is at the end of the image. The box images are stored as a darc archive inside a garc, and it seems all the actual images are just bclims again, probably RGBA5551.
 
Last edited by shinyquagsire23,

suloku

Well-Known Member
Member
Joined
Apr 28, 2008
Messages
883
Trophies
0
XP
866
Country
Ok, my previous statement that PKBank stores TID/SID/name is apparently wrong, because I made the following:

3 (legit) different savegames, each with different TID/SID
Save1: SampleName
Save2: suloku
Save3: suloku

Transfer a pokemon catched in save1 to bank.
Transfer pokemon from bank to save2.
Edit friendship (I could have just walked a little bu meh) and stored in bank again.
Transfer pokemon from bank to save3.

None of the notOT values where updated, Bank treated the pokemon as if it was being returned to the previous owner.

So basically, when the pokemon is transfered from bank to cartridge/digital:

- If it is the original trainer, handler is set to 0 and that's all
- If trainer is not original trainer AND name is not that of notOT handler, notOT data is reset as I previously described
- If trainer is not original trainer AND name is the same of notOT handler,

To test:
- Make sure Bank only relies on notOT name to know if it has to reset the notOT data by using a save with different TID/SID and region (I think I already tested this, but I want to make sure again)
- Test if notOT data is reset in the following situation:
  • OT deposits in bank (a pokemon without notOT data at all)
  • notOT withdraws from bank (notOT data is set)
  • notOT deposits in bank
  • OT withdraws from bank (handler is set to 0)
  • OT deposits in bank
  • notOT withdraws --> will notOT data be reset or will handler just be set to 1 relying in notOT name? My bet is data will reset.

This is interesting behavior since if you have 3 games, and two (or all) share the same trainer name, friendship will be kept between transfers for notOT due to bank only idetifying them by name.
I don't know if nintendo purposedly made it that way so friendship isn't reset when storing in bank if you have several games with the same trainer name. It is convenient though.

Well, I'll keep testing later, this is kind of a pain though, restore save, transfer, check, repeat...

UPDATE: confirmed, bank relies only in notOT namedo determine whether or not it has to reset the data for that pokemon.
Making the other test.

UPDATE 2: I made the second test and I was right: when handler is changed from 0 to 1 the data is reset.
Now I just need to confirm that a different trainer name triggers notOT data reset when the handler is already notOT (again, I think I already made that test, but I can't remember)

UPDATE 3: OK, here's what official bank does when a pokemon is transfered from bank to savegame:

Is savegame trainer the OT?
  • if it is, notOT handler is set to 0x00
  • if it is not the original trainer, the following check is made: is the notOT handler already 0x01?
    • if it is 0x00, it is set to 0x01 and all notOT data is reset, adding a new geolocation.
    • if it is 0x01, the follogin check is made: is notOT name the same as the receiving trainer?
      • if notOT name is blank (all 0x00) or if the names differ, all notOT data is set, including adding a new geolocation data (that can lead to repeated geolocation data).
      • if it is the same name, notOT handler is set to 0x01. There are no TID, SID or regional checks in place, only trainer name.
As you can see, the last check is only trainer name, but I think nintendo did to simplify with the following logic: users will only use bank with their own games, and even if they use a friend's cartridge, the trainer name will most likely be different.
There is no bad outcome to this behavior unless the pokemon has been fed items to purposedly decreades friendship value and the receiver trainer expected it to return to base friendship.
 
Last edited by suloku,
  • Like
Reactions: Margen67

Ekaitz

Redhead Believer
Member
Joined
Jun 13, 2010
Messages
608
Trophies
0
XP
441
Country
France
About eggs storage, the best way to do it would be to "clone" a classic egg trade. (Because I don't think that we can store an egg in the official Bank)
I think that nothing is change when we trade an egg because it doesn't have memory until it hatches and the OT is the people who has it when it hatches.
Eventually, there would be something about the obtention "Trade link" or something like that but it would be a bit stupid to change it.

If we don't touch anything, I think that the egg will be legit when it will hatch. (EXCEPT, EXCEPT if you put it in the bank while using ORAS, it may mess with XY (and vice versa), because of the various locations about the egg obtention. But well, I'm unsure about what I'm telling, that's only suppositions)

Otherwise, I found time to try it, that's working great, you did a great job guy.
If I have the time, I'll do an egg trade and will provide the file here for people to compare. (Btw, I'll watch and compare the file but I may miss something so maybe @suloku will be more accurate than me for that kind of things)

(Oh and great research work about the way the Bank is modifying the Pokemon!)
 
  • Like
Reactions: Margen67

suloku

Well-Known Member
Member
Joined
Apr 28, 2008
Messages
883
Trophies
0
XP
866
Country
If we don't touch anything, I think that the egg will be legit when it will hatch. (EXCEPT, EXCEPT if you put it in the bank while using ORAS, it may mess with XY (and vice versa), because of the various locations about the egg obtention. But well, I'm unsure about what I'm telling, that's only suppositions)
No, it should not mess with XY in any way. I.E. if you trade a pokemon from ORAS to XY location will display "from another land" or something like that due to the game of origin, which is a separate data than location. If pokemon is from XY location will only show in XY.

If I have the time, I'll do an egg trade and will provide the file here for people to compare. (Btw, I'll watch and compare the file but I may miss something so maybe @suloku will be more accurate than me for that kind of things)
That would be great, I can't do any test on that due to only owning one 3ds.

We just need a save or pk6 file from the save before the trade and another one from the save after the trade. I bet it will be the same data, but let's ensure what trade does to eggs.

EDIT: forgot to mention I modified a little my previous post to clarify update 3
 
Last edited by suloku,
  • Like
Reactions: Margen67

Coleman_C18

Well-Known Member
Member
Joined
Sep 1, 2015
Messages
429
Trophies
0
Age
27
XP
345
Country
United States
We just need a save or pk6 file from the save before the trade and another one from the save after the trade. I bet it will be the same data, but let's ensure what trade does to eggs.

I've got my 3ds with pokemon X right next to me, if it could help I can trade you an egg or two.
 
  • Like
Reactions: Margen67

Gocario

GBAFail'd
OP
Member
Joined
Sep 5, 2015
Messages
640
Trophies
0
Location
Bourg Palette
XP
804
Country
France
Ok, my previous statement that PKBank stores TID/SID/name is apparently wrong, because I made the following:

3 (legit) different savegames, each with different TID/SID
Save1: SampleName
Save2: suloku
Save3: suloku

Transfer a pokemon catched in save1 to bank.
Transfer pokemon from bank to save2.
Edit friendship (I could have just walked a little bu meh) and stored in bank again.
Transfer pokemon from bank to save3.

None of the notOT values where updated, Bank treated the pokemon as if it was being returned to the previous owner.

So basically, when the pokemon is transfered from bank to cartridge/digital:

- If it is the original trainer, handler is set to 0 and that's all
- If trainer is not original trainer AND name is not that of notOT handler, notOT data is reset as I previously described
- If trainer is not original trainer AND name is the same of notOT handler,

To test:
- Make sure Bank only relies on notOT name to know if it has to reset the notOT data by using a save with different TID/SID and region (I think I already tested this, but I want to make sure again)
- Test if notOT data is reset in the following situation:
  • OT deposits in bank (a pokemon without notOT data at all)
  • notOT withdraws from bank (notOT data is set)
  • notOT deposits in bank
  • OT withdraws from bank (handler is set to 0)
  • OT deposits in bank
  • notOT withdraws --> will notOT data be reset or will handler just be set to 1 relying in notOT name? My bet is data will reset.

This is interesting behavior since if you have 3 games, and two (or all) share the same trainer name, friendship will be kept between transfers for notOT due to bank only idetifying them by name.
I don't know if nintendo purposedly made it that way so friendship isn't reset when storing in bank if you have several games with the same trainer name. It is convenient though.

Well, I'll keep testing later, this is kind of a pain though, restore save, transfer, check, repeat...

UPDATE: confirmed, bank relies only in notOT namedo determine whether or not it has to reset the data for that pokemon.
Making the other test.

UPDATE 2: I made the second test and I was right: when handler is changed from 0 to 1 the data is reset.
Now I just need to confirm that a different trainer name triggers notOT data reset when the handler is already notOT (again, I think I already made that test, but I can't remember)

UPDATE 3: OK, here's what official bank does when a pokemon is transfered from bank to savegame:

Is savegame trainer the OT?
  • if it is, notOT handler is set to 0x00
  • if it is not the original trainer, the following check is made: is the notOT handler already 0x01?
    • if it is 0x00, it is set to 0x01 and all notOT data is reset, adding a new geolocation.
    • if it is 0x01, the follogin check is made: is notOT name the same as the receiving trainer?
      • if notOT name is blank (all 0x00) or if the names differ, all notOT data is set, including adding a new geolocation data (that can lead to repeated geolocation data).
      • if it is the same name, notOT handler is set to 0x01. There are no TID, SID or regional checks in place, only trainer name.
As you can see, the last check is only trainer name, but I think nintendo did to simplify with the following logic: users will only use bank with their own games, and even if they use a friend's cartridge, the trainer name will most likely be different.
There is no bad outcome to this behavior unless the pokemon has been fed items to purposedly decreades friendship value and the receiver trainer expected it to return to base friendship.
Thanks for you work! It's alot! :o

I "translated" into that piece of code: Would it be good?
Code:
// If the Pokémon isn't already modified.
// Modified it.
if (!pkm->modified && !pkm->isEgg)
{
    // If it's going back to OT
    if (pkm->TID == savedata->TID && pkm->SID == savedata->SID)
    {
        // If it's coming from a non-OT
        if (pkm->currentHandler == 0x01)
        {
            pkm->currentHandler = 0x00;
            pkm->modified = true;
        }
    }
    // If it's going to a non-OT
    else
    {
        // If it is from OT
        if (pkm->currentHandler == 0x00)
        {
            pkm->currentHandler = 0x01;
            // HT data reset
            // + new geo
        }
        // If it is from a non-OT
        else
        {
            bool nameOTH = true;
            if (pkm->HTName != '\0')
            {
                for (uint16_t i = 0; i < 0x18 && nameOTH; i++)
                    if (pkm->HTName[i] != savedata->OTName[i])
                        nameOTH = false;
            }

            // If it is the "same non-OT"
            if (nameOTH)
            {
                // Why setting notOT handler to 0x01 since it's already the case?
                for (uint16_t i = 0; i < 0x18; i++)
                    pkm->HTName[i] = savedata->OTName[i];
            }
            // If it is another non-OT
            else
            {
                // HT data reset
                // + new geo
            }
        }
        pkm->modified = true;
    }
}

I'm still trying to understand romFS ._.
 

suloku

Well-Known Member
Member
Joined
Apr 28, 2008
Messages
883
Trophies
0
XP
866
Country
@Gocario if the nonHT is 0x01 and it is detected as being the same one do to nonHT name being the same, the pokemon should be untouched, just like when returning to original trainer and it already had 0x00 for nonOT handler.

Code:
    }

    // If it is the "same non-OT"
    if(nameOTH){
        ;
    }
    // If it is another non-OT
    else{
 
Last edited by suloku,
  • Like
Reactions: Margen67

Gocario

GBAFail'd
OP
Member
Joined
Sep 5, 2015
Messages
640
Trophies
0
Location
Bourg Palette
XP
804
Country
France
@Gocario if the nonHT is 0x01 and it is detected as being the same one do to nonHT name being the same, the pokemon should be untouched, just like when returning to original trainer and it already had 0x00 for nonOT handler.

Code:
    }

    // If it is the "same non-OT"
    if(nameOTH){
        ;
    }
    // If it is another non-OT
    else{
I was finding this abnormal! D:

Edit: Is there something particular happening when transfering from OT("sugorap") to bank, to notOT("sugorap")?
 
Last edited by Gocario,
  • Like
Reactions: Margen67

Phil5004

Well-Known Member
Member
Joined
Jul 6, 2015
Messages
887
Trophies
0
Age
33
XP
499
Country
Germany
I wanna ask 2 things...
1) Can I use it with my OR CIA (its a selfmade Dump of my Original Copy of the Game)
2) Can we modify it with PKHex?
 
  • Like
Reactions: Margen67

Gocario

GBAFail'd
OP
Member
Joined
Sep 5, 2015
Messages
640
Trophies
0
Location
Bourg Palette
XP
804
Country
France
I wanna ask 2 things...
1) Can I use it with my OR CIA (its a selfmade Dump of my Original Copy of the Game)
2) Can we modify it with PKHex?
1) Can you extract your save from this game with SVDT/SaveDataManager
2) Not the bank. I said in OP: "This homebrew is not intended to cheat. It's just a storage solution."
 
  • Like
Reactions: Margen67

suloku

Well-Known Member
Member
Joined
Apr 28, 2008
Messages
883
Trophies
0
XP
866
Country
Thanks to @Coleman_C18 we figured out how egg trades work:

First of all, eggs can't be deposited in official bank.

A newly generated egg has these values set to 0x00 while in OT savegame:
  • 0xD4-0xD6 Date Met
  • 0xDA-0xDB Met At Location
Whenever the egg is traded, the values are updated. Met at location is set to 0x3275 (this is direct hex view from pk6 file, you should probably use 0x7532), which corresponds to "a Link Trade (Egg)".
Date met is set to console's date (0xD4 is year (0x00-> year 2000, 0x0F-->year 2015, etc), 0xD5 is month (0x01-0C (1-12)), 0xD6 day (0x01-0x1F (1-31)).

This happens always that the egg is traded, regardless if receiver is OT or notOT. Also (obviously) checksum is updated.

I think if egg support is to be added to PHBank, the data should be set to 0x00 when receiver is OT, and simulate a link trade for anybody else. That would make PHBank effectively work only as storage for eggs from original trainer and be as traded eggs for any other trainer. But just setting the data to everyone would be legit too, since that would be as if the egg had been traded, then returned to OT.

I was finding this abnormal! D:

Edit: Is there something particular happening when transfering from OT("sugorap") to bank, to notOT("sugorap")?
Good question, I already checked that with different cartridges, but that might have some flaws.

I'll do this tests:

- Same cartridge, deposit a 0x00 pokemon, then edit save to change TID and SID, withdraw and see what happens.
- Same cartridge, deposit a 0x00 pokemon, then edit save to change trainer name, but mantain TID and SID, withdraw and see what happens.

UPDATE: @Gocario

Made the tests, and as expected, a pokemon OT is identified by 3 components, not just TID/SID, but also name.
This makes a trainer with same name but different TID/SID to be recognized as different trainer.
Also makes a trainer with same TID/SID but different name to be recognized as different trainer.

This meanns the following check (and any other similar ones) should also compare trainer name:
Code:
// If it's going back to OT
if(pkm->TID == savedata->TID && pkm->SID == savedata->SID)
                                     |
                                    \/
if(pkm->TID == savedata->TID && pkm->SID == savedata->SID && strcmp(pkm->HTName, savedata->OTName) == 0)

Responding to your question (Is there something particular happening when transfering from OT("sugorap") to bank, to notOT("sugorap")?: no, nothing particular happens.

And now I've thought that maybe the bank also checks for trainer gender and geolocation data to identify it as different trainer. Need to do more tests...

EDIT: maybe it also uses the following to identify as OT:
0xDF OT Game ID --> what's that?
0xE0 Country ID
0xE1 Region ID
0xE2 3DS Region ID
0xE3 OT Language ID

Regardless of what offcial bank checks aside from TID/SID/NAME, I think that name, tid and SID are more than enough to recognize if the trainer is OT or not, it really makes no differences aside the remote possibility of setting a pokemon as being returned to its OT when in fact it is a different trainer.

EDIT2:
The following data is NOT used to detect if trainer is OT or no.
0xE0 Country ID
0xE1 Region ID
0xE2 3DS Region ID
0xE3 OT Language ID

I still don't know what GAME ID is, and pchex can't change gender for some reason.

EDIT3: well, seems like gender is also used to recognize trainer, but maybe it was the gameID thing.

EDIT 4: OK, I think GAME ID refers to if trainer was generated in pokemon X, pokemon Y, alpha shapphire or rubi omega.

Anyway, after some more tests, I can finally say this is what is checked to identify a trainer: TID, SID, Name, Gender

Note that gender is stored in the pokemon data in the following way:
0xDD Bit 7 set - Female OT Gender

When reading it on 3ds, it might be bit 0 though, due to endianess (haven't really checked)

@Gocario, I made some more edits to this post
 
Last edited by suloku,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: https://youtu.be/5eLWoy0fFkc?si=1vvQ_2zAUlF1ThoD