Jump to content

Prof. 9

Member
  • Posts

    27
  • Joined

  • Last visited

Posts posted by Prof. 9

  1. Nice work! I've actually been working on the same thing but for different games for quite a while now. It's great to see things moving on the Pokémon e-Reader front as well.

    I've also been planning on working to creating a BIN converter to make them able to be scanned using a dot code.

    CaitSith2's nedcmake and nedcenc can do this for you. Nedcmake takes vpk data and header info, and creates a bin file with header, and can create raw and bmp (!) files as well. Nedcenc can transform bin files to raw and vice versa. Personally I've found nedcenc is a bit more reliable when dealing with multi-card applications.

    Is there an IRC channel for this?

  2. This comment is probably long overdue, but is there a reason why Hilbert's sprite isnt included in the "special trainers" list, whilst Hilda's is? Id really love to make a vs. Hilbert battle. Im not sure if his sprite just hasnt been found/is even in the game, or if it was just mistakenly left out.

    Edit: I suppose i should also ask whether or not its possible for Nate and Rosa's sprites to be part of the special trainers list/usable.

    I believe you just get the opposite gender's trainer. So if you play as Nate, you get Hilda, whereas if you play as Rosa, you get Hilbert.

    Incidentally, research by the altwfc.net team showed that the very first byte in the tournament data probably determines which games can download the tournament. 0x00 = Black 2, 0x01 = White 2, 0x02 = Both.

  3. I took a quick look at it and here's what I've come up with.

    Some breakpoints from FireRed US 1.1:

    0x080A0840: check_new_height(poke_id, record_ptr)

    0x080A06B0: calc_hval(pkm_ptr)

    0x080A0784: calc_height(poke_id, hval)

    0x08088E4C: get_dex_height(dex_id)

    0x080A0754: get_hval_class(hval)

    The height of the Pokémon is calculated based on the Pokémon's PID and IVs and normalized, then multiplied by the Pokémon species' average height as listed in the Pokédex. The formulas are below.

    Calculating the hval (^ meaning exclusive OR):

    a = ((iv_atk ^ iv_def) & 0xF) * (iv_hp & 0xF)

    b = ((iv_spatk ^ iv_spdef) & 0xF) * (iv_spe & 0xF)

    hval = (pid & 0xFFFF) ^ (a | (b << 8))

    A lookup table is used for normalization:

    [table]

    [tr][td]class[/td][td]min[/td][td]base[/td][td]size[/td][/tr]

    [tr][td]0[/td][td]0[/td][td]290[/td][td]1[/td][/tr]

    [tr][td]1[/td][td]10[/td][td]300[/td][td]1[/td][/tr]

    [tr][td]2[/td][td]110[/td][td]400[/td][td]2[/td][/tr]

    [tr][td]3[/td][td]310[/td][td]500[/td][td]4[/td][/tr]

    [tr][td]4[/td][td]710[/td][td]600[/td][td]20[/td][/tr]

    [tr][td]5[/td][td]2710[/td][td]700[/td][td]50[/td][/tr]

    [tr][td]6[/td][td]7710[/td][td]800[/td][td]100[/td][/tr]

    [tr][td]7[/td][td]17710[/td][td]900[/td][td]150[/td][/tr]

    [tr][td]8[/td][td]32710[/td][td]1000[/td][td]150[/td][/tr]

    [tr][td]9[/td][td]47710[/td][td]1100[/td][td]100[/td][/tr]

    [tr][td]10[/td][td]57710[/td][td]1200[/td][td]50[/td][/tr]

    [tr][td]11[/td][td]62710[/td][td]1300[/td][td]20[/td][/tr]

    [tr][td]12[/td][td]64710[/td][td]1400[/td][td]5[/td][/tr]

    [tr][td]13[/td][td]65210[/td][td]1500[/td][td]2[/td][/tr]

    [tr][td]14[/td][td]65410[/td][td]1600[/td][td]1[/td][/tr]

    [tr][td]15[/td][td]65510[/td][td]1700[/td][td]1[/td][/tr]

    [/table]

    Height class is determined from the largest minimum that's less than the hval.

    Normalized hval calculation:

    hnorm = base + (hval - min) / size

    The Pokémon's average height in meters is pulled from the Pokédex data to calculate the individual Pokémon size in meters. In the ROM the height is stored multiplied by 10, hence the division below.

    hmeter = hdex * hnorm / 10

    Finally, the height is converted to inches as such:

    hinch = hmeter * 100 / 254

  4. I hope for the improvement of this tournament editor like editing all 7 trainer(no filler trainer) and making them in full stats.
    This will never be possible as the game only has room for 4 trainers per tournament in the save file. You will always need at least 3 filler trainers.
  5. It turns out the Pokémon data (including the names), at least the quicksave in-dungeon party data, is compressed by simply removing all unused bits. For instance if there are two variables, one that uses 3 bits and one that uses 4, they're squashed into a single byte. Because of this all the bytes of the names (and other data) are shifted. After un-shifting them you'll get normal characters that you can interpret using the table file. So there's no proprietary character encoding voodoo going on. :)

    I haven't looked at it much yet, but here's a quick method I wrote to do the unshifting. It's not optimized but it should be good enough for a proof of concept: http://pastebin.com/aCSaTmh2

    To use, load the save file (or the relevant part of it at least) into a Stream, set it to the position of the name and call decode() with the right parameters. Here are some that work:

    0x8413: startbit 3, bits 80 (starter's name)

    0x8457: startbit 5, bits 80 (partner's name)

    I'll probably look into this more later. If you want to see for yourself, the routine that decompresses the quicksave party data starts at 0x02059BA0 in RAM. The actual call to the decompression routine to decompress a name is at 0x02059DCC.

  6. Since you used RubenPikachu's program, I can't help you with that; even though DTE was built on top of PWT Editor, it implements its own extra features, and I haven't had any tournaments corrupt on me with PWT Editor.
    You'll have to ask RubenPikachu. Maybe it doesn't get saved?
  7. ...
    The tournaments you linked seem to have invalid checksums, so they are detected by PWT Editor and the game as corrupt. This could be due to using a hex editor to make changes, or bugs in the tool(s) you used. Since you used RubenPikachu's program, I can't help you with that; even though DTE was built on top of PWT Editor, it implements its own extra features, and I haven't had any tournaments corrupt on me with PWT Editor.

    If you really want to import these, use a hex editor to truncate them to 0x1210 bytes and import them as Raw Data in PWT Editor.

    Edit:Another question, you can only enter a maximum of 3 tournaments?
    Yes. Three tournaments is the max that you can fit in a save file.
  8. 0x487 uses proprietary character encoding, terminated with 01 then 00's, while 0x13F is ANSI.
    It's mostly ANSI, but some characters were removed and/or replaced with different characters.

    Here's a table file: http://www.mediafire.com/?xb0dxr9tl8ed2tp All the bullet characters are graphically the same, and 5B is glitchy. [$NN] denotes a character that the game doesn't support (meaning it's either a regular space, a solid square, or butchers the text display).

  9. I tried to open DTE

    and I tried to edit my PWT.

    But this happens....(Look at the attachment)

    How would I fix this?

    P.S. My save file ain't corrupted. Its still working!

    This can happen when your save file is not in the standard format, for example when you're using an emulator such as No$gba (which by default compresses all save files). Try converting your save file to RAW format before you load them.
  10. Well, none of the currently released tournaments have had more than 4 trainers as far as I know so I doubt there is such a variable. Here's a compilation of all the stuff that's been figured out so far, I don't think I've posted it here yet:

    Tournament (0x1210 bytes):
    0x0000: Tournament settings (0x274 bytes)
    0x0274: Trainer 1 (0x3E0 bytes)
    0x0654: Trainer 2 (0x3E0 bytes)
    0x0A34: Trainer 3 (0x3E0 bytes)
    0x0E14: Trainer 4 (0x3E0 bytes)
    0x11F4: Bracket (0x1C bytes)
    
    Trainer data (0x3E0 bytes):
    0x000: Pokémon 1 (0x34 bytes)
    0x034: Pokémon 2 (0x34 bytes)
    0x068: Pokémon 3 (0x34 bytes)
    0x09C: Pokémon 4 (0x34 bytes)
    0x0D0: Pokémon 5 (0x34 bytes)
    0x104: Pokémon 6 (0x34 bytes)
    0x138: Trainer settings (0x2A8 bytes)
    
    TOURNAMENT SETTINGS:
    0x000 = ?
    0x001 = ?
    0x002 = ?
    0x003 = ?
    0x004 = ?
    0x005 = ?
    0x006 = ?
    0x007 = Language (None, Japanese, English, French, Italian, German, Spanish, Korean)
    0x008 = Tournament ID (16-bit)
    0x00A = Tournament Name (37 characters)
    0x054 = Tournament Description (75 characters)
    0x0EA = Battle Rules (111 characters)
    0x1C8 = Minimum amount of Pokémon required
    0x1C9 = Maximum amount of Pokémon allowed (also the amount the opponent will use)
    0x1CA = Allowed Level (8-bit)
    0x1CB = Level style (0x00 = normal, 0x01 = minimum, 0x02 = maximum, 0x03 = scale down, 0x04 = set, 0x05 = scale up)
    0x1CC = Maximum total party level (16-bit)
    0x1CE = Allow duplicate Pokémon (1 bit)
    0x1CF = Allow duplicate items (1 bit)
    0x1D0 = Banned Pokémon (656 bits, 1 bit per species)
    0x222 = Banned Items (608 bits, 1 bit per item)
    0x26E = ? (always 0?)
    0x26F = Battle Type (2 bits) (Single Battle, Double Battle, Triple Battle, Rotation Battle)
    0x270 = Use World Champion battle music instead of PWT Finals battle music (1 bit)
    0x271 = Allowed Type (8-bit) (if 0x11, all types are allowed)
    0x272 = Banned Move (single 16-bit value; only 1 move can be banned (Sky Drop?)?)
    
    TRAINER DATA:
    0x138 = Name (16 characters)
    0x158 = Class (22 characters)
    0x184 = Custom intro message (74 characters)
    0x218 = Custom loss message (74 characters)
    0x2AC = Custom win message (74 characters)
    0x340 = Unknown message (74 characters)
    0x3D4 = Sprite
    0x3D5 = Pre-set intro message
    0x3D6 = Pre-set loss message
    0x3D7 = Pre-set win message
    0x3D8 = In-battle loss message
    0x3D9 = In-battle win message
    0x3DA = Pre-battle Announcer message
    0x3DB = ?
    0x3DC = ? (16-bit) (max: 0xF?)
    0x3DE = ?
    0x3DF = ?
    
    BRACKET:
    0x00 = Trainer 1 bracket data (4 bytes)
    0x04 = Trainer 2 bracket data (4 bytes)
    0x08 = Trainer 3 bracket data (4 bytes)
    0x0C = Trainer 4 bracket data (4 bytes)
    0x10 = Trainer 5 bracket data (4 bytes)
    0x14 = Trainer 6 bracket data (4 bytes)
    0x18 = Trainer 7 bracket data (4 bytes)
    
    BRACKET DATA:
    0x0 = Pokémon data source (0 = random from set 1, 1 = random from set 2, 2 = from tournament data, 3 = ?)
    0x1 = Trainer Rank
    0x2 = Special Trainer (16-bit)

  11. It looks like the 2012 Masters Division Challenge (ENG10003) was silently updated; Abel's Metagross had his Ice Beam changed to Ice Punch and the : was removed from the name to make it distinct from the old one.

    I've gathered all the PWT files I had (most from this thread, some Italian ones I found on GBARL) and put them in a ZIP with ID tags and the correct names. You can download that here: http://www.mediafire.com/?2wj2bv0jhyr6811

    Work on PWTEditor has stalled, I've been busy with other stuff and I'm not really satisfied with how it's turned out so I'll be rewriting parts of it sometime in the future. For what it is though (a PWT extractor/inserter) it should do the trick just fine.

  12. Nice work. I should get around to finishing that editor of mine; can't really think of a good way to handle trainer sprite/name/class/message selection in the GUI...

    I noticed that 3 is also a valid value for the PKM data setting.

    Based on the mode value (XX) and the special Trainer value (ZZ), two variables are cached:

    Mode 0:

    0x00 = 0x44 + rand(10)

    0x01 = 0

    Mode 1:

    0x00 = 0x4E + rand(10)

    0x01 = 0

    Mode 2:

    0x00 = Special Trainer value

    0x01 = 0xF1 + trainerNumber (0-6)

    Mode 3:

    0x00 = Special Trainer value

    0x01 = 0

    note: rand(10) takes numbers 0-9 in a random order, so it doesn't generate any duplicates

    The game then looks at 0x01 first. If it's 0xFF, it takes the player's team and continues. If it's 0xF1, 0xF2, 0xF3 or 0xF4, it looks at the special Trainer value; if that's zero, it takes the Trainer sprite value in the trainer's data.

  13. I'm starting to think it's impossible to change the rewards. I set all the variables that we don't know about yet (first 7 bytes + language byte, 0x26E, last 5 bytes of a trainer) to 0xFF, and I still got 2 BP in the end EDIT: and regular Shards.

    EDIT2:

    ...

    0x1C Book Girl (Female)

    0x1D Maid (Female)

    there's more...

    Sometimes the ones after schoolkid don't work... dunno why yet.

    Looks like there are no more regular Trainer sprites you can use, the game defaults to 0 for values >= 0x1E.

    EDIT3: The pre-set intro messages change depending on when you fight the trainer in the tournament. EDIT4: Oh, you already listed those. Didn't see the buttons at the bottom.

    EDIT5:

    XX = PKM Data Setting

    02 - Defined within .pwt

    01 - Defined randomly within narc 2

    00 - Defined randomly within narc 1

    Note: I think the difference between 01 and 00 is just the NARC it grabs from. There's 2 that contain sets; the game would pick randomly.

    It turns out that 0x03 is also a valid value. Using it forces the game to use the special trainer override value (shifted by one, so 0 = Cheren, etc.) and forces the pre-set battle message. It also makes the game use pre-set teams, but I'm not sure where they're being taken from. When I tried to fight Marlon, he sent out Golbat, Zangoose, Watchog and Klink.

    EDIT6: The 16-bit value at 0x3DC in the trainer data seems to be some kind of bitfield (though only the lower 4 bits appear to be used) that's apparently used during battle. The 0x8 bit is shifted 4 places to the left (so 0xF results in 0x87).

  14. For the sake of editing, 3D5/3D6/3D7 should be set by the player, thus be 0. The only thing that isn't set is the Announcer Text, which can also be set to 0 since it calls the "Trainer Extra" (at the time I didn't know its function).

    So essentially all of these could be set to 0 and defined by the Editor.

    Well, the preset text has one extra perk, namely that it's automatically translated to all other languages (not sure why you'd do that since the tournament name/description/ruleset is in English but hey, the option is there). I think I'll check for presets when the text is being saved and put a combobox next to the edit box for choosing presets, once I get around to working on the editor a bit more (been focusing on actually playing the game the past week). That would also be helpful for people who don't really care/can't think of anything.
  15. Hello everybody, this is my first post here! First of all, sorry for my English, I'm Italian.

    I'm trying to use these Japanese Tournaments in my Italian White2, they all work fine except for "The Legendary Rotation Battle!". Before the main menu appears, there is a message that can be translated into "PWT data has been erased" or something like that. If I have other tornaments in my save file, only "The Legendary Rotation Battle!" gets erased.

    I used Prof. 9's PWTEditor to import the .pwt files.

    Any ideas? :)

    Turns out one of the things I listed in Step 2 of tournament insertion wasn't entirely correct, I was just writing 0x00000001 to 0xA0/0xA4/0xA8 but the game expects what I think is the savecount of the tournament datablock to be there, and the savecount for Legendary Rotation Battle was 2 for whatever reason. It should be fixed in the new PWTEditor (see below).

    I've been working on my PWT editor a bit and you can now change basic stuff like descriptors, rules and banlists in a cramped GUI. Can't edit trainers yet though. I've tried to make it impossible to set impossible rules like 6 Pokémon minimum with max total party level 1, or a higher minimum required amount of Pokémon than the maximum allowed.

    PbTR5.png

    Download PWTEditor v0.2.1 (source included): http://www.mediafire.com/?tq2gh4v5w0mtn2a

    I should think of a better name for this.

  16. This seems to be the basic memory layout:

    Tournament (0x1210 bytes):

    0x0000: Tournament settings (0x274 bytes)

    0x0274: Trainer 1 (0x3E0 bytes)

    0x0654: Trainer 2 (0x3E0 bytes)

    0x0A34: Trainer 3 (0x3E0 bytes)

    0x0E14: Trainer 4 (0x3E0 bytes)

    0x11F4: ??? (0x1C bytes)

    Trainer data (0x3E0 bytes):

    0x000: Pokémon 1 (0x34 bytes)

    0x034: Pokémon 2 (0x34 bytes)

    0x068: Pokémon 3 (0x34 bytes)

    0x09C: Pokémon 4 (0x34 bytes)

    0x0D0: Pokémon 5 (0x34 bytes)

    0x104: Pokémon 6 (0x34 bytes)

    0x138: Trainer settings (0x2A8 bytes)

    A bunch of tournament settings that I figured out the meaning of:

    0x000 = ?

    0x001 = ?

    0x002 = ?

    0x003 = ?

    0x004 = ?

    0x005 = ?

    0x006 = ?

    0x007 = ?

    0x008 = ?

    0x009 = ?

    0x00A = Tournament Name (37 characters)

    0x054 = Tournament Description (75 characters)

    0x0EA = Battle Rules (111 characters)

    0x1C8 = Minimum amount of Pokémon required

    0x1C9 = Maximum amount of Pokémon allowed (also the amount the opponent will use)

    0x1CA = Allowed Level (8-bit)

    0x1CB = Level style (0x00 = normal, 0x01 = minimum, 0x02 = maximum, 0x03 = scale down, 0x04 = set, 0x05 = scale up)

    0x1CC = Maximum total party level (16-bit)

    0x1CE = Allow duplicate Pokémon (1 bit)

    0x1CF = Allow duplicate items (1 bit)

    0x1D0 = Banned Pokémon (656 bits, 1 bit per species)

    0x222 = Banned Items (608 bits, 1 bit per item)

    0x26E = ?

    0x26F = Battle Type (2 bits) (Single Battle, Double Battle, Triple Battle, Rotation Battle)

    0x270 = Use World Champion battle music instead of PWT Finals battle music (1 bit)

    0x271 = Allowed Type (8-bit) (if 0x11, all types are allowed)

    0x272 = Banned Move (single 16-bit value; only 1 move can be banned (Sky Drop?)?)

    Surprising amount of rules you can make with this. 0x26E seems to be always 0 and 0x00-0x09 I can't get any breaks from, so I have no idea what they do.

    EDIT: rectified a typo: level style 0x05 should be scale up, not set.

  17. Got tournament injection and removal working:

    faZeE.png

    Here's how it's done:

    Step 1: Copy tournament block

    Just write the whole tournament block (0x1314 bytes) to 0x7A000, 0x7B400 or 0x7C800. Make sure all checksums are valid!

    See my previous post for notes on this.

    Step 2: Set in block index

    The block index is located at 0x19400 and 0x3F400. The game uses this to keep track of which extra storage blocks are used. To enable a tournament block after you've inserted it, write 0xC21E to 0x52, 0x54 or 0x56, and take the 32-bit value at 0x1304 in the tournament block and write it to 0xA0, 0xA4 or 0xA8. Afterwards, fix this checksum:

    0xB0: CRC-16 CCITT of 0x00-0xB0 (0xB0)

    Step 3: Update checksum list

    The checksum list is located at 0x25F00 and 0x4BF00. The game uses this to check for corrupted blocks. Basically, take the checksum for the block index from step 2 and write it to 0x36. Finally, fix this last checksum:

    0xA2: CRC-16 CCITT of 0x00-0x94 (0x94)

    I've been working on a program to modify tournaments. At the moment, it can import and extract tournaments from a save file, as well as dump and load the raw tournament data (i.e. the first 0x1210 bytes of a tournament file); it will take care of all checksumming and stuff automatically. This should simplify tinkering with and experimenting on the data. It's still very much a work in progress, so there's not much to see yet. Source is included (but it's not the neatest thing I've ever written), and you'll need the .NET Framework 2.0 to run it. Hasn't been thoroughly tested, so use at your own risk, I guess.

    http://www.mediafire.com/?8xh1eu37aiceb3x

    So, time to start collecting those tournament files?

    EDIT: Fixed step 2.

  18. I was able to change the name of the new English tournament (before it was reissued) through save hacking:

    C13hM.png

    Haven't done anything else yet, but I'll probably look into this some more.

    Here are my notes:

    SAVE OFFSET: 0x7A000

    Size: 0x1314 (?)

    CHECKSUMS:

    0x1210: CRC-16 CCITT of 0x0000-0x1210 (0x1210)

    0x1216: CRC-16 CCITT of 0x0000-0x1214 (0x1214)

    0x1300: CRC-16 CCITT of 0x0000-0x1214 (0x1214)

    0x1312: CRC-16 CCITT of 0x1300-0x1304 (0x0004)

    Basically the tournament data has a checksum, then there is a checksum of the tournament data plus the checksum, stored in two places, and finally there's a checksum of THAT checksum.
×
×
  • Create New...