Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

36 Excellent


About Bond697

  • Rank
  • Birthday 09/24/1984

Recent Profile Visitors

21878 profile views
  1. Wild Pokémon and stationary legendaries without a shiny check have their PIDs created in the same way. It involves using the TID and SID to evaluate the seed being used for the PID and whether or not it should be OR-ed with 0x80000000 on creation. ---------------------------------------------------------------------------------------------------- standard 0x8 decision pid generation(btw, r6 is sidtid for basically this entire thing) 020056FC F096ECB6 blx #0209C06C //switch to ARM, to 0209C06C (umul64()) -return to 02005700 02005700 6922 ldr r2,[r4,#0x10] // load value at 2216254 into r2(00269EC3) 02005702 6963 ldr r3,[r4,#0x14] // load 02216258 into r3(aka, zero-out r3) 02005704 1810 add r0,r2,r0 // add together r0 and r2, finish l32 advancement 02005706 414B adc r3,r1 // new upper seed 02005708 6020 str r0,[r4] // store the lower half-rng back to the state offset 0200570A 6063 str r3,[r4,#0x4] // store the upper half-rng back to the state offset 0200570C 2D00 cmp r5, #0x0 // this is 0 for pid creation only 0200570E D101 bne #0x2005714 // false, no branch 02005714 6860 ldr r0,[r4,#0x4] // load the value of the upper half of the rng state into r0 02005716 2100 mov r1, #0x0 // set r1 to 00000000 02005718 2300 mov r3, #0x0 // set r3 to 00000000 0200571A 1C2A mov r2, r5 // move contents r5(0x0) to r2 0200571C F096ECA6 blx #0209C06C // no branch 02005720 1C08 mov r0,r1 //save that u32 02005722 BD38 pop {r3-r5,r15} //jump to 20186F8 020186F8 1C04 mov r4,r0 //save the seed to compare 020186FA E024 b #0x2018746 02018746 9807 ldr r0,[sp,#0x1C] // value @ 2FE3604(0x2) 02018748 2800 cmp r0,#0x0 0201874A D019 beq #0x2018780 0201874C 2801 cmp r0,#0x1 0201874E D002 beq #0x2018756 02018750 2802 cmp r0,#0x2 02018752 D01E beq #0x2018792 ;true 02018792 2001 mov r0,#0x1 02018794 9906 ldr r1,[sp,#0x18] 02018796 0400 lsl r0,r0,#0x10 //prepping for base 0x00010000 xor 02018798 1C22 mov r2,r4 0201879A 4002 and r2,r0 //not understanding why it ANDs u32 by 10000, but r2 now == 0 0201879C 0409 lsl r1,r1,#0x10 0201879E 428A cmp r2,r1 // same as with the legendaries, 10000 vs. 20000, not equal(this is ability-setting junk) 020187A0 D000 beq #0x20187A4 // false, no advancement 020187A2 4044 eor r4,r0 // base xor by 00010000 020187A4 1C20 mov r0,r4 // store this half-ready pid to r0 and save it... 020187A6 BDF8 pop {r3-r7,r15} 021A9DB2 79A1 ldrb r1,[r4,#0x6] //2FE36C4- pull a byte out of a local array- this byte determines the type of PID- HL, standard, gift, etc 021A9DB4 2902 cmp r1,#0x2 // r1 = 0 021A9DB6 D012 beq #0x21A9DDE // false, no branch 021A9DB8 6A2C ldr r4,[r5,#0x20] //load sidtid to r4 021A9DBA 0401 lsl r1,r0,#0x10 //set the lower half of the temp pid to r1(u16 of r1, need to fix) 021A9DBC 0C0B lsr r3,r1,#0x10 // move the lower half temp-pid to the lower half of r3 to prep 021A9DBE 0421 lsl r1,r4,#0x10 // separate tid and sid; this is tid 021A9DC0 0C22 lsr r2,r4,#0x10 // sid is ready 021A9DC2 0C09 lsr r1,r1,#0x10 // tid is ready 021A9DC4 4051 eor r1,r2 // tid ^ sid 021A9DC6 1C1A mov r2,r3 // move lower 16 of pid to r2, get ready for next step 021A9DC8 404A eor r2,r1 l16 pid ^ (tid ^ sid) 021A9DCA 2101 mov r1,#0x1 // r1 = 1 021A9DCC 4211 tst r1,r2 // (tid ^ sid ^ l16 pid) & 1 (= 0 in my case) 021A9DCE D004 beq #0x21A9DDA // resolve to 0, skip this 021A9DD0 2102 mov r1,#0x2 // set up 0x8 or 021A9DD2 0789 lsl r1,r1,#0x1E // r1 = 80000000 021A9DD4 B002 add sp,#0x8 021A9DD6 4308 orr r0,r1 // this is an OR, not XOR 021A9DD8 BD70 pop {r4-r6,r15} //return 021A9DDA 4902 ldr r1,=#0x7FFFFFFF // set up to finish the pid 021A9DDC 4008 and r0,r1 // unset the highest bit, though it's probably not set as it is 021A9DDE B002 add sp,#0x8 021A9DE0 BD70 pop {r4-r6,r15} // return
  2. I think you got confused. 10anniv otg is: (rand() >> 7) & 1 if 0, ot gender is 1, if 1, ot gender is 0 so take the highest bit of the lower byte of rand(). if it's 0, ot gender is 1, if 1, then otg is 0. 0x31 is the ot gender field in the pkm RAM:02013A66 FC F7 D9 FE BL rand RAM:02013A6A C0 11 ASRS R0, R0, #7 ; rand >> 7 & 1 RAM:02013A6C 38 40 ANDS R0, R7 ; gender decision RAM:02013A6E 00 28 CMP R0, #0 RAM:02013A70 0C D0 BEQ loc_2013A8C RAM:02013A72 00 20 MOVS R0, #0 RAM:02013A74 41 46 MOV R1, R8 ; r8 is sp+0x15 RAM:02013A76 08 70 STRB R0, [R1] ; set sp+0x15 to 0 RAM:02013A78 0A E0 B loc_2013A90 RAM:02013A78 ; --------------------------------------------------------------------------- RAM:02013A7A 00 00 ALIGN 4 RAM:02013A7C A0 B7 01 02 off_2013A7C DCD pp_name ; DATA XREF: createPkm+Er RAM:02013A7C ; createPkm+58r RAM:02013A80 14 60 00 03 dword_2013A80 DCD 0x3006014 ; DATA XREF: createPkm+14r RAM:02013A84 00 00 FF FF dword_2013A84 DCD 0xFFFF0000 ; DATA XREF: createPkm+2Cr RAM:02013A88 FF FF 00 00 dword_2013A88 DCD 0xFFFF ; DATA XREF: createPkm+30r RAM:02013A8C ; --------------------------------------------------------------------------- RAM:02013A8C RAM:02013A8C loc_2013A8C ; CODE XREF: createPkm+C0j RAM:02013A8C 40 46 MOV R0, R8 ; r8 is sp+0x15 RAM:02013A8E 07 70 STRB R7, [R0] ; set sp+0x15 to 1 RAM:02013A90 RAM:02013A90 loc_2013A90 ; CODE XREF: createPkm+C8j RAM:02013A90 30 1C MOVS R0, R6 ; pkm RAM:02013A92 31 21 MOVS R1, #0x31 ; ot gender RAM:02013A94 42 46 MOV R2, R8 ; this is the data ptr with the ot gender decision RAM:02013A96 FE F7 83 FA BL setPkmPartyData RAM:02013A9A 07 B0 ADD SP, SP, #0x1C RAM:02013A9C 38 BC POP {R3-R5} RAM:02013A9E 98 46 MOV R8, R3 RAM:02013AA0 A1 46 MOV R9, R4 RAM:02013AA2 AA 46 MOV R10, R5 RAM:02013AA4 F0 BC POP {R4-R7} RAM:02013AA6 01 BC POP {R0} RAM:02013AA8 00 47 BX R0
  3. i have no doubt they're exactly the same aside from the obvious changes to ot and whatever else.
  4. This might sound dumb, but the first thing to do might be to see if any of the trash is actually thumb code. If so, those are probably the first ones generated. Could the ones with none have been traded to a gamecube game and back? The trash bytes for the 10anniv pokes exist because GF does a copy of the pokemon's name from a global constant to a local buffer, then copies the local buffer to the .pkm "file" in memory. The problem is, the first copy is just a strcpyFF(local_buf, global_const) which ends at the 0xFF terminator, so if the name in the variable was 'LUGIA'\xFF FF FF FF, they would only copy 'LUGIA'\0xFF, leaving the last 3 or however many bytes as whatever was on the stack before because they don't zero-out the full size of the local variable before the copy. Then they would copy the name using strncpy(&pkm.name, local_buf, 10) without caring about the junk past the FF-terminated name. The thumb code on the stack that makes up the trash is because of a function that 's basically memcpyFF(dest, src) that copies until it hits an 0xFF that I think is copying waaay too far and is coincidentally not breaking anything so they either didn't notice or left it.
  5. This is the info for it: You can see the text is (poorly) translated and not localized. https://dl.dropboxusercontent.com/u/13004170/meteor_jirachi.zip
  6. I don't remember what I did anymore, actually, aside from pulling the roms out of the game cart. I think I decompressed it, but I'm not sure.
  7. Ohh, ok. I was told none of them had items. The one I was looking at was the lugia rom and that one has the light ball in it. I'll have to pull out the other ones.
  8. Fun fact since you brought this up: the 10ANNIV multiboot roms have unused code in them to give all 10ANNIV pokes a light ball. Must be a leftover from another event somewhere or something since the 10ANNIVs have no item.
  9. When I was given the 10ANNIV rom 3 1/2 years ago, the person who gave it to me asked me not to give it out or anything to preserve the cart's value. The same goes for a few others. Some of the stuff isn't even private, there just hasn't been anyone who has really cared, as far as I knew. Like this for example: It's an unreleased gen 3 event, METEOR Jirachi. I found its multiboot rom in.. some game. I've told people about it and given out archives, but nobody really seemed to care that much. I spent awhile gathering the multiboot roms and checking them out and to be honest, I didn't realize there was much interest in them anymore until Sabresite mentioned them not too long ago.
  10. All rise for Judge Guested in the Project Pokemon People's Court. [ATTACH=CONFIG]13789[/ATTACH] What's the case today? [ATTACH=CONFIG]13790[/ATTACH] Two dummies, who may be the same person, having a slapfight on the internet, your honor. [ATTACH=CONFIG]13787[/ATTACH] And the verdict is... [ATTACH=CONFIG]13788[/ATTACH] Guilty! Of being stupid on the internet. I think we're done here. So help me if we have to do this again after the judge's ruling, I will start ending careers so fast. ( ͡° ͜ʖ ͡°)
  11. Bond697

    GameFreak Gen 6 Data

    HeapData Offset Description 0x0 Heap pointer 0x4 Bitflags for heap Heap Bitflags Offset Description 0 In use 1 Main heap Pokemon Accessor Offset Type Description 0x0 u32 vtable pointer 0x4 u32 is pkm in party 0x8 u32 pointer to pkm data 0xC bool is pkm data encrypted 0xD bool encrypt pkm data (?) Pokemon Temp Data Offset Type Description 0x0 u32 Encryption constant 0x8 u64 pid and 0 0x10 u32 tid/sid 0x18 u16 National dex ID 0x1A u8 Form 0x1E u16 Gender 0x20 u16 Nature 0x22 u8 Ability number 0x23 u8 Pid count to generate to increase shiny chance 0x24 u16 HP IV 0x26 u16 ATK IV 0x28 u16 DEF IV 0x2A u16 SPA IV 0x2C u16 SPD IV 0x2E u16 SPE IV 0x30 u32 Friendship 0x6C u8 Language idx 0x6D u8 Country ID 0x6E u8 Trainer mem text 0x6F u8 3DS Region gfl::fs::ver4::ArcFileAccessor Data Offset Description 0x0 vtable 0x4 Ptr to GARC memory block 0x8 Ptr to FATO data in block 0xC Ptr to FATB data in block 0x10 Ptr to FIMB data in block
  12. pokemon data works differently in gen 6. in gen 3/4/5, pointers to specific pokes were passed directly into functions. in gen 6, a higher-level struct is passed in that contains different pokemon info. also, in gens 3/4/5, data was read from and written to pkms by only 2-4 functions. those 2-4 functions were switch statements that were up to a couple hundred cases. so for example. in gen 3/4/5, you had something like this: u8 PKM_getNature(void* pkm) { PKM_decryptPartyPoke(pkm); u8 nature = PKM_readPartyPkmStat(pkm, FIELD_ABILITY, NULL); PKM_encryptPartyPoke(pkm); return nature; } in gen 6, it looks more like this: u8 PKM_getNature(void* pkm_data) { PKM_decryptPartyPoke(pkm_data); struct PKM_blk0* b0 = PKM_getBlock0ShuffleTypePtr(pkm_data, 1); u8 pk_nature = b0->nature; PKM_encryptPartyPoke(pkm_data); return pk_nature; } in the first function, void* pkm is the actual pkm file in ram. in the second, pkm_data is a set of data about a pkm. the data struct looks like this so far: 0 - 4 - is pkm is party (this is used in PKM_decryptPoke and PKM_encryptPoke to decide what exactly to en/decrypt 8 - pkm pointer C - bool is pkm encrypted D - bool encrypt pkm so as you can see, while data is handled by PKM_readPartyPkmStat in the former, gen 6 actually reads each piece of data out in the get function for that data. they use functions to get pointers to each of the shuffled blocks and read from there.
  13. http://projectpokemon.org/forums/showthread.php?44315
  14. We might be able sort of RNG by starting the game and finding the seed you started on and looking for good seeds from there.
  • Create New...