Welcome, this is the discussion board of TASVideos.
Addr 0x4C: High byte of camera position of end of current level? Addr 0xC7: Buttons read from joypad 1 (this frame) Addr 0xC8: Last frame's buttons. Copied from 0xC7 before 0xC7 is refilled Addr 0xCA: Value to write to PPUCTRL (0x2000) Addr 0xCE: Y screen position (low?) (pixels) Addr 0xCC/0xCD: X screen position (pixels) Addr 0xEC: Screen mode? 0x01 = Title screen 0x02 = Title screen idle animation 0x03 = Title screen -> First level 0x04 = Filler/between screens 0x05 = Playable level Addr 0x617/0x618: X position of the character on the whole stage (pixels) Addr 0x84 and 0x87: Integers indicating the cardinal direction joypad 1's dpad is being held. 0x84 will only show U/D/L/R and 0x87 will only show U/D/L/R/UR/UL/DR/DL. 0x84: 1 = Up 2 = Down 3 = Left 4 = Right 0 = Direction not listed above 0x87: 1 = Up 2 = Down 3 = Left 4 = Right 5 = Up + Left 6 = Up + Right 7 = Down + Left 8 = Down + Right 0 = Direction not listed above Addr 0x91/0x92: X position of the character on the screen (sub-pixels) Addr 0xA9: Speed gained from riding an enemy/apple Fetched from [0x583 + enemy_slot_id] Addr 0x98/0x99: Speed (sub-pixels) Addr 0x9A: Effective speed (pixels). This is the sum of the whole pixel speed and any boost Addr 0xA9: Speed boost added to the regular speed. It looks like speed can be pretty well optimized by keeping a close eye on the effective speed in 0x9A and trying to keep it high. You have a running speed (holding B) of 2 pixels per frame and can get a boost of 2 more from bomb jumping. Address 0x53: For level 1, starts at 0x08, gets changed to 0when screen scroll X becomes 0x0808 Maybe some kind of switch to load other level data? Address 0xA8: Seems to be flags 0x80 = Being hit? 0x20 = riding enemy? 0x01 = On ground? Addr 0x4ED: Seems to be a counter of how many enemies have been seen? Seems like the high 6 bytes are also used to compare against the high byte for the player position (ish). Addr 0x4F1: Enemy slot ID that hit you Addr 0x4F3-0x4FA (8 slots): 0x00 = Slot empty 0x02 = Enemy is on screen 0x03 = Enemy is off screen Addr 0x4FB-0x500 (6 slots): Seems like enemy type ID Only related to enemies (not apples, range is 0-5) if value is 0x15 a section of code doesn't run Other values checked for: 0x13, 0x10, 0x39, 0x3B, 0x3C, 0x3F, 0x44, 0x46, 0x00, 0x16 Addr 0x501-0x508 (8 slots): ? Related to enemies compared == 0x0D at 0xE8FF Addr 0x51B-0x520 (6 slots): An offset into a pointer table for animation data for this specific enemy Seems to choose what animation this enemy should perform (move vertically upwards, oscillate up and down/left and right, etc) Used at D507 to get an address in bank 3 (A9B2 + value * 2) Addr 0x521-0x526 (6 slots): ? Related to enemies Looks like a counter for this enemy, probably used to determine where in the animation cycle the enemy is Used as an offset to the address fetched via the above value [(bank 3)A9B2 + [0x51B + enemy_slot_id * 2]] + [0x521 + enemy_slot_id * 2] * 4 = addr of the start of some data for enemy Entries in the data are probably 4 bytes, and this value is used to get the data for the current frame. If the first value in the next entry is 0x80 this counter restarts (and 0x515 + enemy_slot_id is incremented) Addr 0x527-0x52E (8 slots): ? Related to enemies Flags 0x40 - might indicate enemy is dying? Seems like you can't be damaged by them if it is set. 0x80 - is often cleared when updating/checking enemies might indicate player is riding this enemy? 0x08 - ? if set you can't get hit by it? you also can't ride it 0x04 - ? if set you can't get hit by it? Addr 0x535-0x53C (8 slots): ? Related to enemies compared < 0x04 at 0xE906 if true, sets 0x40 in flags 0xA8 Addr 0x543-0x54A (8 slots): Enemy X position (high) Addr 0x54B-0x552 (8 slots): Enemy X position (low) Addr $0563-0x56A (8 slots): Enemy Y position Addr 0x573-0x57A (8 slots): ? Related to enemies Might be hitbox horizontal size Addr 0x57B-0x582 (8 slots): ? Related to enemies Might be hitbox vertical size Function 0xE994 Seems to check player against enemy position. hitbox_h = [0x573 + enemy_slot_id] + 0x07 hitbox_w = [0x57b + enemy_slot_id] + 0x0F This function checks if the follow are all true: player_y < (enemy_y + hitbox_h) Make sure player is not too low (enemy_x - hitbox_w) < (screen_scroll_X + player_onscreen_x) Make sure player is not too far left (screen_scroll_X + player_onscreen_x) < (enemy_x + hitbox_w) Make sure player is not too far right (enemy_y - hitbox_h) < player_y Make sure player is not too high (enemy_y - hitbox_h) - player_y is stored to 0x0006 This value must be negative to fit the condition above If this value -1 to -8 the game considers you as riding the enemy Bank 3: Starting at 0xB1AA is an array of addresses B1CE - level 00 (??) BB16 - level 01 B1CE - level 02 B648 - level 03 B822 - level 04 B94E - level 05 B32A - level 06 B4AA - level 07 B9F6 - level 08 B744 - level 09 B3E4 - level 10 BA68 - level 11 BBE8 - level 12 B1CE - level 13 (??) B1CE - level 14 (??) B1CE - level 15 (??) B1CE - level 16 (??) B1CE - level 17 (??) These addresses point to a data for the powerup boxes in each level. Each entry in those arrays is 6 bytes long:  - X screen pos (high)  - X screen pos (low)  - ?  - X pos on screen  - Y pos  - Type Seems like this list of boxes is terminated with 0xFF in  and  Known types: 1 -> Extra life 2 -> ? 3 -> Burger 4 -> Heart 5 -> Apple Function F176: This function runs level specific code. Using the level ID (address 0x51) it looks up an address: 0xF19B + (level_id * 2) 0xF19A + (level_id * 2) It then uses the section ID (address 0x52) to get a function address addr + (section_id * 2) The value fetched is pushed to the stack, then an RTS instruction is issued. RTS pushes the (16 bit value from stack + 1) to PC, so the addresses stored in the rom are 1 off from the start of the function Most levels have more than one function pointer in this area. The function is usually to handle moving to the next section or world, or to determine when you have finished the world (usually the last section handler) (Function addresses in this table have already had 1 added to them) Section 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Level 00 (???) [F1C0] F23C Level 01 [F1C2] F243 F287 Level 02 [F1C6] F294 F2AB Level 03 [F1CA] F2B8 F2D7 F330 Level 04 [F1D0] F337 F362 F3A0 Level 05 [F1D6] F3AC F3DD Level 06 [F1DA] F40A F40A F40A F433 F458 Level 07 [F1E4] F468 F4D4 Level 08 [F1E8] F4E1 F4F8 Level 09 [F1EC] F505 F505 F505 F505 F505 F521 F540 F576 Level 10 [F1FA] F58B F5B2 F5E8 Level 11 [F200] F5F8 F60F Level 12 [F204] F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F61C F713 F733 World 1 section 0 (F243): Handles the "Good luck" guy When the screen scroll reaches 0x0808 addr 0x53 is changed from 0x08 to 0x00 If Screen scroll X == 0x0BXX, level section is increased (boss is triggered) World 1 section 1 (F287): Waits for 0x4F3 (Object enabled) to become 0 World 2 section 0 (F294): If Screen scroll X == 0x17XX, level section is increased (boss is triggered) World 2 section 1 (F2AB): Waits for 0x4F3 (Object enabled) to become 0 World 3 section 0 (F2B8): If Screen scroll X == 0x16XX, level section is increased (boss is triggered?) World 3 section 1 (F2D7): ??? if 0xE2 >= 5, move to section 2 World 3 section 2 (F330): Seems to be hard coded to move to the next world. World 4 section 0 (F337): If Screen scroll X == 0x0FXX, level section is increased (boss is triggered?) World 4 section 1 (F362): ??? Similar to W3S1 World 4 section 2 (F3A0): ??? Similar to W3S2 World 5 section 0 (F3AC): If block player is in front of (0x615) == 0x79, level section is increased (move to boss room) World 5 section 1 (F3DD): ??? World 6 section 0-2 (F40A): If block player is in front of (0x615) == 0x38, level section is increased (causes a screen transition?) If Screen scroll X == 0x13XX, level section is increased World 6 section 3 (F433): ??? World 6 section 4 (F458): Waits for 0x4F3 (Object enabled) to become 0 World 7 section 0 (F468): ?complex stuff? If Screen scroll X == 0x16XX, level section is increased World 7 section 1 (F4D4): Waits for 0x4F3 (Object enabled) to become 0 World 8 section 0 (F4E1): If Screen scroll X == 0x0BXX, level section is increased World 8 section 1 (F4F8): Waits for 0x4F3 (Object enabled) to become 0 World 9 section 0-4 (F505): If block player is in front of (0x615) == 0x30, level section is increased (causes a screen transition?) If block player is in front of (0x615) == 0x83, level section is increased (causes a screen transition?) World 9 section 5 (F521): If Screen scroll X == 0x20XX, level section is increased World 9 section 6 (F540): ??? Similar to W3S1 World 9 section 7 (F576): ??? World 10 section 0 (F58B): If Screen scroll X == 0x0FXX, level section is increased World 10 section 1 (F5B2): Monitors 0x4F3 and 0x4F4 ??? World 10 section 2 (F5E8): Waits for 0x4F3 (Object enabled) to become 0 World 11 section 0 (F5F8): If Screen scroll X == 0x0BXX, level section is increased World 11 section 1 (F60F): Waits for 0x4F3 (Object enabled) to become 0 World 12 section 0-20 (F61C): ??? There is a table at 0xF781 used to compare the block the player is in front of, and to decide where to warp the player: Block ID Map section BF -- 01 7A -- 0F C0 -- 00 C1 -- 10 30 -- 11 BD -- 12 BE -- 13 ??? World 12 section 21 (F713): Waits for 0x4F3 (Object enabled) to become 0 World 12 section 22 (F733): Waits for 0x4F3 (Object enabled) to become 0 Movement when riding an enemy: Your final movement speed is calculated from a number of different sources 0xA9 is probably the horizontal speed gained from riding an enemy Skipping shop: at 0xF7B0 the burger count (0x61E) is compared to 0 which skips a function that likely starts the shop routine. Title screen: Address 0x22 is a counter for the start button. It is reset to 4 and counts down when the start button is held. When the counter reaches 0 the game advances to the next screen/into the game. Level timer length: There is table at 0xC3D6 which specifies the timer length per level: Level 00? - 0xC3D6 = 24792 ??? Level 01 - 0xC3D8 = 300 Level 02 - 0xC3D8 = 300 Level 03 - 0xC3D8 = 400 Level 04 - 0xC3D8 = 400 Level 05 - 0xC3D8 = 300 Level 06 - 0xC3D8 = 400 Level 07 - 0xC3D8 = 400 Level 08 - 0xC3D8 = 300 Level 09 - 0xC3D8 = 500 Level 10 - 0xC3D8 = 300 Level 11 - 0xC3D8 = 200 Level 12 - 0xC3D8 = 500 Castle: Section 0x02 has two doors. The left door warps you to section 00 (entrance to the castle). The right door warps you to the left side of section 0x10, which looks identical to section 0x02. Going back through the door in section 0x10 brings you to section 0x0F, which is also identical to 0x02 and 0x10. Seems like 0x02 starts from the elevator down, 0x10 starts from the room on the left, and 0x0F starts from the door on the right. Ending level 11 on a 0x30 block ID wrong warps you to section 0x11 which looks like a hidden shop. Taking the elevator up takes you to section 0x08 which is identical to 0x0C. This is around halfway through the castle. Section 0x12 and 0x13 start from falling out of the ceiling on section 0x03. Section 0x05 is 0x03 coming down from the elevator from section 0x04. Section 0x07 is 0x03 on the elevator back from 0x06. Section 0x0D is 0x03 coming down from the elevator from section 0x0C Section 0x14 is the same as 0x15 (final boss room). Section 0x16 is a glitched version of 0x00 and 0x01 combined. Level data ROM bank: The table at 0xC5AD says what bank each level's data is in: Level 01 - 3 Level 02 - 3 Level 03 - 0 Level 04 - 0 Level 05 - 1 Level 06 - 2 Level 07 - 0 Level 08 - 1 Level 09 - 3 Level 10 - 1 Level 11 - 2 Level 12 - 3 Address 0x4f-0x50 This address is filled from a table at 0xD102. The address fetched is then incremented by 3 before being stored to 0x4F and 0x50 Level 01 - 8000 + 3 = 8003 Level 02 - 8000 + 3 = 8003 Level 03 - 90b7 + 3 = 90BA Level 04 - 8000 + 3 = 8003 Level 05 - 8000 + 3 = 8003 Level 06 - a0b4 + 3 = A0B7 Level 07 - 9133 + 3 = 9136 Level 08 - 8953 + 3 = 8956 Level 09 - a0ee + 3 = A0F1 Level 10 - 90d3 + 3 = 90D6 Level 11 - 930c + 3 = 930F Level 12 - a206 + 3 = A209 Address 0x54-0x55 This address is filled from a table at 0xCD9F. Level 01 - 9c0a Level 02 - 800f Level 03 - 801b Level 04 - 90d2 Level 05 - 8013 Level 06 - 8013 Level 07 - a0cb Level 08 - 914e Level 09 - 8962 Level 10 - a112 Level 11 - 90e6 Level 12 - 931b Fetching level data: All accesses are in the bank for thr level. See the table above to find that bank. The address in 0x54-0x55 is for the level data. The address in 0x4F-0x50 is for a table of offsets into the level data. Each offset is 208 bytes long. To fetch level data: Take the high byte of the position Use that as an offset into the table from 0x4F-0x50 and fetch a byte value Take the value, multiple it by 208, and add it to the address in 0x54-0x55 The resulting address is the beginning of that segment of data. Enemy data Table in bank 5 at 0xAF63, add level_id * 2 Level 01 - b9d7 Level 02 - af87 Level 03 - b507 Level 04 - b697 Level 05 - baa7 Level 06 - b117 Level 07 - b377 Level 08 - bbb7 Level 09 - b7a7 Level 10 - b267 Level 11 - bc87 Level 12 - bd57 That address points to another table, entries are 4 bytes long. Game fetches 0x4ED, multiplies it by 4, and adds it to get an address. Note: this addition (0xD24F) seems wrong and may have issues with bit overflow if the lower byte would overflow. Might be abusable for something? .b - Enemy position (low byte) .b - Enemy Y position? .b - Enemy type? .b - ??? 0x4ED seems to have room for 4 enemies per high position byte. If any of those are unused the data is all 0 in the above table. Enemy spawn: Starting at 0xD229 0x4ED seems to hold the next(?) enemy id to load for the level. The following must be true for the enemy to spawn: Player's position high byte must be <= end of level (0x4C) (Player's position + 0x90) (high byte) == Enemy high position byte (Player's position + 0x90) (low byte) < Enemy low position byte (Player's position + 0x193) (high byte) >= Enemy high position byte if equal: (Player's position + 0x193) (low byte) > Enemy low position byte what this boils down to is that the game checks every half screen (0x80 pixels) and increments the counter if you are in the first 4 pixels. you can skip the spawns for that half screen by being at 5 speed at a point where you move the screen from 0x7F->0x84 or 0xFF->0x04 World/Section Min/Max: Table at 0xBC00 (bank 4), indexed by level_id * 2. These are pointers to data for each world: Level 01 - bc36 Level 02 - bc56 Level 03 - bc76 Level 04 - bca6 Level 05 - bcc6 Level 06 - bce6 Level 07 - bd16 Level 08 - bd36 Level 09 - bd56 Level 10 - bdb6 Level 11 - bdd6 Level 12 - bdf6 Fetch that address and add section_id * 16 Data in that table: .b = Min camera position .b = Max camera position
I also modified my Wizards & Warriors III Lua script to exhaustively generate vertical jump information, but analysis of the first 0x3000000 trials showed that all of the data was present after the first 0x2000. Only ran it in the first level, though. I can upload that info, if desired, but it may not be useful due to the bomb boosts/jumps.
0x95 Y-position of player character 0x94 Y-subpixel 0x9C Y-speed of player character 0x9D Y-subpixel speed 0x9E Max X-speed 0x9F Max X-subpixel speed 0xA0 Max Y-speed 0xA1 Max Y-subpixel speed 0xA8 flags 0x00 = jumping or falling 0x01 = standing on ground 0x02 = jumping/falling/standing/whatever against a barrier 0x20 = standing on platform / enemy / projectile 0x80 = taking damage 0xAB flags related to jumping 0x00 = not jumping 0x01 = jumping 0x02 = falling after jumping 0xAC Counter related to jumping
09:24 <FatRatKnight> In any case, I am aware that along with A9 for boost speed, you missed the sub-boost speed at AA. 09:24 <FatRatKnight> Or boost subspeed, I guess. 09:24 <FatRatKnight> Somewhere a sub should be. 09:24 <Warepire> Interesting. 09:25 <FatRatKnight> The fractional value is mostly pertinent for riding apples, as enemies generally have a lovely zero for their subspeed. 09:26 <Warepire> That means we also missed the subpixel boost value in the enemy data structures 09:26 <FatRatKnight> My notes claim that would be 058B, along with the following 7 addresses. 09:30 <Warepire> May I paste relevant bits in the topic later? 09:31 <FatRatKnight> Go ahead.