![]() |
Routines |
| Prev: B294 | Up: Map | Next: B453 |
|
Used by the routine at DrawList.
Draws one sprite into the off-screen play window buffer. The sprite is found using the type in the draw list entry, as an index into the table of sprite pointers at SpritePointers. A sprite has a two byte header (the width in bytes plus flags, then the height in pixel rows) followed by its pixel rows, each made of pairs of bytes, one pair for each byte of width. The first byte of each pair is ORed onto the buffer and the second is then XORed onto the result. The rows are stored from the bottom of the sprite to the top. A sprite whose width and height are both zero is blank and is not drawn. Bit 7 of the type in the draw list entry means the sprite is drawn facing the other way. The flag in bit 7 of the sprite's own header records which way its data is currently stored, and if the two differ then the sprite's data is flipped in place first, using FlipSprite. The x position is a pixel position in the buffer, where 10 is the left edge of the play window. The y position is the height of the bottom of the sprite above the bottom of the buffer, so it increases up the screen: 30 is the bottom of the play window and A0 is the top. Sprites that overlap the top or bottom are clipped, and 10 pixels either side are available for sprites that overhang the left or right edge. If the sprite is not on a byte boundary then each pair of bytes is shifted right by the number of pixels using the tables built by BuildShiftTables, and an extra byte is written for each row. The drawing is done by unrolled loops at DrawSprite_Shifted (shifted) and DrawSprite_Unrolled (byte aligned), which are entered part way along according to the width of the sprite so that exactly the right number of bytes are drawn on each row. The sprite data is read by pointing the stack pointer at it and using POP.
|
||||||||||||
|
Find the sprite for this entry.
|
||||||||||||
| DrawSprite | B2BC | LD A,(IX+$00) | Fetch the type. | |||||||||
| B2BF | ADD A,A | Double it, discarding the "face the other way" bit, to give the offset into the table of pointers. | ||||||||||
| B2C0 | LD L,A | Add the offset to the address of the table of sprite pointers at SpritePointers. | ||||||||||
| B2C1 | LD H,$00 | |||||||||||
| B2C3 | LD BC,$60A3 | |||||||||||
| B2C6 | ADD HL,BC | |||||||||||
| B2C7 | LD E,(HL) | Fetch the address of the sprite into DE. | ||||||||||
| B2C8 | INC HL | |||||||||||
| B2C9 | LD D,(HL) | |||||||||||
| B2CA | LD A,(DE) | Fetch the width byte of the header into C. | ||||||||||
| B2CB | LD C,A | |||||||||||
| B2CC | INC DE | Fetch the height from the header. | ||||||||||
| B2CD | LD A,(DE) | |||||||||||
| B2CE | OR C | Combine them and keep bits 0-5. | ||||||||||
| B2CF | AND $3F | |||||||||||
| B2D1 | RET Z | Return if both the width and the height are zero, as the sprite is blank. | ||||||||||
| B2D2 | DEC DE | Point DE at the start of the header again. | ||||||||||
| B2D3 | CALL FlipSprite | Flip the sprite data if it is stored facing the wrong way, using FlipSprite. | ||||||||||
|
Find which page of the shift tables to use, which depends on the x position within a byte.
|
||||||||||||
| B2D6 | LD A,(IX+$01) | Fetch the x position. | ||||||||||
| B2D9 | DEC A | Take one off, shift the result left by one (multiplying by two) and keep only the three bits of the shift, so that this is the shift amount multiplied by two. | ||||||||||
| B2DA | RLCA | |||||||||||
| B2DB | AND $0E | |||||||||||
| B2DD | OR $E0 | Add the base of the shift tables to give the page number, in H. | ||||||||||
| B2DF | LD H,A | |||||||||||
| B2E0 | LD A,(IX+$01) | Fetch the x position again. | ||||||||||
| B2E3 | AND $07 | Test whether it is a multiple of 08. | ||||||||||
| B2E5 | LD A,(DE) | Fetch the width byte of the header. | ||||||||||
| B2E6 | JP Z,DrawSprite_Aligned | Jump to DrawSprite_Aligned to draw the sprite without shifting if the x position is exactly on a byte boundary. | ||||||||||
|
The sprite needs shifting, so it will cover one more byte on each row than its width.
|
||||||||||||
| B2E9 | INC A | Add one to the width in bytes. | ||||||||||
| B2EA | AND $0F | |||||||||||
| B2EC | LD ($9621),A | Store it as the number of bytes written to the buffer for each row. | ||||||||||
| B2EF | LD C,A | Take a copy of it. | ||||||||||
| B2F0 | ADD A,$17 | Add 17 to give the amount to subtract to get from the end of one row of the buffer to the start of the row above, since each row is 18 bytes long. | ||||||||||
| B2F2 | LD ($B3A5),A | Write that as the number to subtract in the SUB instruction at B3A4. | ||||||||||
| B2F5 | LD A,C | Fetch the width back, plus one. | ||||||||||
| B2F6 | DEC A | Take one off to get the width. | ||||||||||
| B2F7 | INC DE | Point DE at the height. | ||||||||||
| B2F8 | NEG | Negate the width and keep the bottom two bits, so that this is the number of unused copies of the unrolled loop out of the four available. | ||||||||||
| B2FA | AND $03 | |||||||||||
| B2FC | ADD A,A | Multiply by 0E, the length of one copy of the unrolled loop. | ||||||||||
| B2FD | LD B,A | |||||||||||
| B2FE | ADD A,A | |||||||||||
| B2FF | ADD A,B | |||||||||||
| B300 | ADD A,A | |||||||||||
| B301 | ADD A,B | |||||||||||
| B302 | LD B,H | Hold the shift table page in B. | ||||||||||
| B303 | LD HL,$B36B | Point HL at DrawSprite_Shifted. | ||||||||||
| B306 | CALL AddAToHL | Add the offset using AddAToHL, to skip the copies that are not needed. | ||||||||||
| B309 | LD ($B369),HL | Write the address into the jump at DrawSprite_Shifted_Jump, so that it enters the loop at the right place. | ||||||||||
| B30C | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B30D | LD ($9622),A | Store it as the number of rows still to draw. | ||||||||||
| B310 | LD H,B | Put the page number back into H. | ||||||||||
| B311 | LD C,(IX+$01) | Fetch the x position into C. | ||||||||||
| B314 | LD B,(IX+$02) | Fetch the y position into B. | ||||||||||
|
Clip the bottom of the sprite, if it is below the bottom of the play window.
|
||||||||||||
| B317 | LD A,B | Is the bottom of the sprite on or above the bottom of the play window (30)? | ||||||||||
| B318 | CP $30 | |||||||||||
| B31A | JR NC,DrawSprite_Shifted_Address | Jump to DrawSprite_Shifted_Address if so. | ||||||||||
| B31C | LD L,A | Keep the y position. | ||||||||||
| B31D | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B31E | ADD A,L | Add the y position to get the top of the sprite. | ||||||||||
| B31F | CP $30 | Is the top of the sprite below the bottom of the play window? | ||||||||||
| B321 | RET C | Return if it is, as the sprite is not visible at all. | ||||||||||
| B322 | LD A,$30 | Work out how many rows of the sprite are below the play window. | ||||||||||
| B324 | SUB L | Subtract the y position from the bottom of the play window. | ||||||||||
| B325 | LD L,A | Keep that number of rows. | ||||||||||
| B326 | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B327 | SUB L | Take away the number of rows that are cut off. | ||||||||||
| B328 | RET Z | Return if nothing is left. | ||||||||||
| B329 | LD ($9622),A | Store the number of rows that are left to be drawn. | ||||||||||
| B32C | PUSH HL | Save the number of rows that are cut off. | ||||||||||
| B32D | LD A,($9621) | Fetch the number of bytes written for each row. | ||||||||||
| B330 | DEC A | Take one off to get the width in bytes. | ||||||||||
| B331 | LD B,A | Use it as a counter. | ||||||||||
| B332 | XOR A | Start the total at zero, and clear the high byte of HL. | ||||||||||
| B333 | LD H,A | |||||||||||
| DrawSprite_Shifted_Multiply | B334 | ADD A,L | Add the number of rows that were cut off to the total, once for each byte of the width, to multiply them. | |||||||||
| B335 | DJNZ DrawSprite_Shifted_Multiply | |||||||||||
| B337 | LD L,A | Keep the size of the hidden rows. | ||||||||||
| B338 | ADD HL,HL | Double it, as each byte of the width has a pair of bytes of data. | ||||||||||
| B339 | ADD HL,DE | Add the address of the sprite to give the address of the first visible row of data. | ||||||||||
| B33A | EX DE,HL | Keep the address of the first visible row. | ||||||||||
| B33B | POP HL | Restore HL. | ||||||||||
| B33C | LD B,$30 | Start drawing from the bottom of the play window. | ||||||||||
|
Find the address in the buffer and point the stack pointer at the sprite data.
|
||||||||||||
| DrawSprite_Shifted_Address | B33E | CALL GetBufferAddress | Find the address in the buffer of the first byte to draw, using GetBufferAddress. | |||||||||
| B341 | LD ($9623),SP | Save the stack pointer. | ||||||||||
| B345 | EX DE,HL | Point the stack pointer at the sprite, so that POP fetches the data. | ||||||||||
| B346 | LD SP,HL | |||||||||||
| B347 | EX DE,HL | |||||||||||
| B348 | INC SP | Take it past the height byte, to the first pair of data bytes. | ||||||||||
|
Clip the top of the sprite, if it is above the top of the play window.
|
||||||||||||
| B349 | LD A,(IX+$02) | Fetch the y position. | ||||||||||
| B34C | CP $A0 | Jump to DrawSprite_Done to finish if it is, as the sprite is not visible. | ||||||||||
| B34E | JP NC,DrawSprite_Done | |||||||||||
| B351 | LD L,A | Keep the y position. | ||||||||||
| B352 | LD A,($9622) | Fetch the number of rows to draw. | ||||||||||
| B355 | ADD A,L | Add the y position to get the top of the sprite. | ||||||||||
| B356 | SUB $A0 | Subtract the top of the play window. | ||||||||||
| B358 | JR C,DrawSprite_Shifted_Rows | Jump if the sprite does not reach above the top of the play window. | ||||||||||
| B35A | LD L,A | Keep the number of rows that are cut off. | ||||||||||
| B35B | LD A,(DE) | Take the cut off rows away from the number of rows to draw. | ||||||||||
| B35C | SUB L | |||||||||||
| B35D | LD ($9622),A | |||||||||||
| DrawSprite_Shifted_Rows | B360 | LD A,($9622) | Fetch the number of rows to be drawn. | |||||||||
| B363 | EXX | Switch to the shadow registers, and keep the number of rows to draw in B'. | ||||||||||
| B364 | LD B,A | |||||||||||
| DrawSprite_Shifted_Row | B365 | EXX | Switch back to the main registers. | |||||||||
| B366 | POP DE | Fetch the first pair of data bytes into DE. | ||||||||||
| B367 | LD A,(BC) | Fetch the first byte of the buffer to be changed. | ||||||||||
| DrawSprite_Shifted_Jump | B368 | JP DrawSprite_Shifted_Jump | Jump into the unrolled loop. | |||||||||
|
The unrolled loop that draws one row of a sprite that is not on a byte boundary. BC points at the buffer, DE holds the current pair of data bytes (OR byte in E and XOR byte in D) and H holds the shift table page. Each pair of bytes is split by the shift table into a left part that is merged into the buffer byte already in A and a right part that is merged into the next buffer byte.
|
||||||||||||
| DrawSprite_Shifted | B36B | LD L,E | Merge the left part of the shifted pair into the buffer byte already in A: OR on the shifted OR byte and XOR on the shifted XOR byte. Store the result and move on to the next buffer byte, and the right half of the shift table. | |||||||||
| B36C | OR (HL) | |||||||||||
| B36D | LD L,D | |||||||||||
| B36E | XOR (HL) | |||||||||||
| B36F | LD (BC),A | |||||||||||
| B370 | INC BC | |||||||||||
| B371 | INC H | |||||||||||
| B372 | LD L,E | Merge the right part of the shifted pair into the next buffer byte and leave it in A, as the next pair also overlaps it. Go back to the left half of the table and fetch the next pair of data bytes. | ||||||||||
| B373 | LD A,(BC) | |||||||||||
| B374 | OR (HL) | |||||||||||
| B375 | LD L,D | |||||||||||
| B376 | XOR (HL) | |||||||||||
| B377 | DEC H | |||||||||||
| B378 | POP DE | |||||||||||
| B379 | LD L,E | Merge the left part of the second pair and store it. | ||||||||||
| B37A | OR (HL) | |||||||||||
| B37B | LD L,D | |||||||||||
| B37C | XOR (HL) | |||||||||||
| B37D | LD (BC),A | |||||||||||
| B37E | INC BC | |||||||||||
| B37F | INC H | |||||||||||
| B380 | LD L,E | Merge the right part of the second pair and fetch the third. | ||||||||||
| B381 | LD A,(BC) | |||||||||||
| B382 | OR (HL) | |||||||||||
| B383 | LD L,D | |||||||||||
| B384 | XOR (HL) | |||||||||||
| B385 | DEC H | |||||||||||
| B386 | POP DE | |||||||||||
| B387 | LD L,E | Merge the left part of the third pair and store it. | ||||||||||
| B388 | OR (HL) | |||||||||||
| B389 | LD L,D | |||||||||||
| B38A | XOR (HL) | |||||||||||
| B38B | LD (BC),A | |||||||||||
| B38C | INC BC | |||||||||||
| B38D | INC H | |||||||||||
| B38E | LD L,E | Merge the right part of the third pair and fetch the fourth. | ||||||||||
| B38F | LD A,(BC) | |||||||||||
| B390 | OR (HL) | |||||||||||
| B391 | LD L,D | |||||||||||
| B392 | XOR (HL) | |||||||||||
| B393 | DEC H | |||||||||||
| B394 | POP DE | |||||||||||
| B395 | LD L,E | Merge the left part of the fourth pair and store it. | ||||||||||
| B396 | OR (HL) | |||||||||||
| B397 | LD L,D | |||||||||||
| B398 | XOR (HL) | |||||||||||
| B399 | LD (BC),A | |||||||||||
| B39A | INC BC | |||||||||||
| B39B | INC H | |||||||||||
| B39C | LD L,E | Merge the right part of the fourth pair. | ||||||||||
| B39D | LD A,(BC) | |||||||||||
| B39E | OR (HL) | |||||||||||
| B39F | LD L,D | |||||||||||
| B3A0 | XOR (HL) | |||||||||||
| B3A1 | DEC H | |||||||||||
| B3A2 | LD (BC),A | Store the last buffer byte of the row. | ||||||||||
|
Move up to the start of the previous row of the buffer. The number to subtract is written by B2F2 for each sprite.
|
||||||||||||
| B3A3 | LD A,C | Subtract the number of bytes to step back (the operand of this instruction is modified) from the low byte of the buffer address. | ||||||||||
| B3A4 | SUB $00 | |||||||||||
| B3A6 | LD C,A | |||||||||||
| B3A7 | JP NC,DrawSprite_Shifted_Next | Take a carry from the high byte if there was a borrow. | ||||||||||
| B3AA | DEC B | |||||||||||
| DrawSprite_Shifted_Next | B3AB | EXX | Switch to the shadow registers, where B' holds the number of rows left to draw. | |||||||||
| B3AC | DJNZ DrawSprite_Shifted_Row | Loop back until every row of the sprite has been drawn. | ||||||||||
| DrawSprite_Done | B3AE | LD SP,($9623) | Restore the stack pointer. | |||||||||
| B3B2 | RET | Return. | ||||||||||
|
The sprite is on a byte boundary, so no shifting is needed and each pair of bytes is combined with just one byte of the buffer.
|
||||||||||||
| DrawSprite_Aligned | B3B3 | AND $0F | Keep the width of the sprite in bytes. | |||||||||
| B3B5 | LD ($9621),A | Store it as the number of bytes written to the buffer for each row. | ||||||||||
| B3B8 | LD C,A | Take a copy of it. | ||||||||||
| B3B9 | ADD A,$17 | Add 17 to give the amount to subtract to get back to the start of the row above, once the last byte of a row has been written. | ||||||||||
| B3BB | LD ($B447),A | Write that as the number to subtract in the SUB instruction at B446. | ||||||||||
| B3BE | LD A,C | Fetch the width back. | ||||||||||
| B3BF | INC DE | Point DE at the height. | ||||||||||
| B3C0 | NEG | Negate the width and keep the bottom two bits, so that this is the number of unused copies of the unrolled loop out of the four available. | ||||||||||
| B3C2 | AND $03 | |||||||||||
| B3C4 | LD C,A | Keep the number of unused copies of the loop. | ||||||||||
| B3C5 | ADD A,A | Multiply by 06, the length of one copy of the unrolled loop. | ||||||||||
| B3C6 | ADD A,C | |||||||||||
| B3C7 | ADD A,A | |||||||||||
| B3C8 | LD HL,$B42E | Point HL at DrawSprite_Unrolled. | ||||||||||
| B3CB | CALL AddAToHL | Add the offset using AddAToHL, to skip the copies that are not needed. | ||||||||||
| B3CE | LD ($B42C),HL | Write the address into the jump at DrawSprite_Aligned_Jump, so that it enters the loop at the right place. | ||||||||||
| B3D1 | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B3D2 | LD ($9622),A | Store it as the number of rows still to draw. | ||||||||||
| B3D5 | LD C,(IX+$01) | Fetch the x position into C. | ||||||||||
| B3D8 | LD B,(IX+$02) | Fetch the y position into B. | ||||||||||
|
Clip the bottom of the sprite, as in B317.
|
||||||||||||
| B3DB | LD A,B | Is the bottom of the sprite on or above the bottom of the play window (30)? | ||||||||||
| B3DC | CP $30 | |||||||||||
| B3DE | JR NC,DrawSprite_Aligned_Clip | Jump to DrawSprite_Aligned_Clip if so. | ||||||||||
| B3E0 | LD L,A | Keep the y position. | ||||||||||
| B3E1 | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B3E2 | ADD A,L | Add the y position to get the top of the sprite. | ||||||||||
| B3E3 | CP $30 | Is the top of the sprite below the bottom of the play window? | ||||||||||
| B3E5 | RET C | Return if it is, as the sprite is not visible at all. | ||||||||||
| B3E6 | LD A,$30 | Work out how many rows of the sprite are below the play window. | ||||||||||
| B3E8 | SUB L | Subtract the y position from the bottom of the play window. | ||||||||||
| B3E9 | LD L,A | Keep that number of rows. | ||||||||||
| B3EA | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B3EB | SUB L | Take away the number of rows that are cut off. | ||||||||||
| B3EC | RET Z | Return if nothing is left. | ||||||||||
| B3ED | LD ($9622),A | Store the number of rows that are left to be drawn. | ||||||||||
| B3F0 | PUSH HL | Save the number of rows that are cut off. | ||||||||||
| B3F1 | LD A,($9621) | Fetch the width of the sprite in bytes. | ||||||||||
| B3F4 | LD B,A | Use it as a counter. | ||||||||||
| B3F5 | XOR A | Start the total at zero, and clear the high byte of HL. | ||||||||||
| B3F6 | LD H,A | |||||||||||
| DrawSprite_Aligned_Multiply | B3F7 | ADD A,L | Add the number of rows that were cut off to the total, once for each byte of the width, to multiply them. | |||||||||
| B3F8 | DJNZ DrawSprite_Aligned_Multiply | |||||||||||
| B3FA | LD L,A | Keep the size of the hidden rows. | ||||||||||
| B3FB | ADD HL,HL | Double it, as each byte of the width has a pair of bytes of data. | ||||||||||
| B3FC | ADD HL,DE | Add the address of the sprite to give the address of the first visible row of data. | ||||||||||
| B3FD | EX DE,HL | Keep the address of the first visible row. | ||||||||||
| B3FE | POP HL | Restore HL. | ||||||||||
| B3FF | LD B,$30 | Start drawing from the bottom of the play window. | ||||||||||
| DrawSprite_Aligned_Clip | B401 | CALL GetBufferAddress | Find the address in the buffer of the first byte to draw, using GetBufferAddress. | |||||||||
| B404 | LD ($9623),SP | Save the stack pointer. | ||||||||||
| B408 | EX DE,HL | Point the stack pointer at the sprite, so that POP fetches the data. | ||||||||||
| B409 | LD SP,HL | |||||||||||
| B40A | EX DE,HL | |||||||||||
| B40B | INC SP | Take it past the height byte, to the first pair of data bytes. | ||||||||||
|
Clip the top of the sprite, as in B349.
|
||||||||||||
| B40C | LD A,(IX+$02) | Fetch the y position. | ||||||||||
| B40F | CP $A0 | Jump to DrawSprite_Done to finish if it is, as the sprite is not visible. | ||||||||||
| B411 | JP NC,DrawSprite_Done | |||||||||||
| B414 | LD L,A | Keep the y position. | ||||||||||
| B415 | LD A,($9622) | Fetch the number of rows to draw. | ||||||||||
| B418 | ADD A,L | Add the y position to get the top of the sprite. | ||||||||||
| B419 | SUB $A0 | Subtract the top of the play window. | ||||||||||
| B41B | JR C,DrawSprite_Aligned_Rows | Jump if the sprite does not reach above the top of the play window. | ||||||||||
| B41D | LD L,A | Keep the number of rows that are cut off. | ||||||||||
| B41E | LD A,(DE) | Fetch the height of the sprite. | ||||||||||
| B41F | SUB L | Take the cut off rows away from the number of rows to draw. | ||||||||||
| B420 | LD ($9622),A | Store the number of rows to be drawn. | ||||||||||
| DrawSprite_Aligned_Rows | B423 | LD A,($9622) | Fetch the number of rows to be drawn. | |||||||||
| B426 | LD H,B | Move the buffer address into HL. | ||||||||||
| B427 | LD L,C | |||||||||||
| B428 | EXX | Switch to the shadow registers, and keep the number of rows to draw in B'. | ||||||||||
| B429 | LD B,A | |||||||||||
| DrawSprite_Aligned_Row | B42A | EXX | Switch back to the main registers. | |||||||||
| DrawSprite_Aligned_Jump | B42B | JP DrawSprite_Aligned_Jump | Jump into the unrolled loop. | |||||||||
|
The unrolled loop that draws one row of a sprite on a byte boundary. HL points at the buffer and each pair of data bytes is fetched into DE: the OR byte (E) is ORed onto the buffer byte and the XOR byte (D) is XORed onto the result.
|
||||||||||||
| DrawSprite_Unrolled | B42E | POP DE | Merge the first pair of data bytes with the buffer byte and move on. | |||||||||
| B42F | LD A,E | |||||||||||
| B430 | OR (HL) | |||||||||||
| B431 | XOR D | |||||||||||
| B432 | LD (HL),A | |||||||||||
| B433 | INC HL | |||||||||||
| B434 | POP DE | Merge the second pair of data bytes with the buffer byte and move on. | ||||||||||
| B435 | LD A,E | |||||||||||
| B436 | OR (HL) | |||||||||||
| B437 | XOR D | |||||||||||
| B438 | LD (HL),A | |||||||||||
| B439 | INC HL | |||||||||||
| B43A | POP DE | Merge the third pair of data bytes with the buffer byte and move on. | ||||||||||
| B43B | LD A,E | |||||||||||
| B43C | OR (HL) | |||||||||||
| B43D | XOR D | |||||||||||
| B43E | LD (HL),A | |||||||||||
| B43F | INC HL | |||||||||||
| B440 | POP DE | Merge the fourth pair of data bytes with the buffer byte. | ||||||||||
| B441 | LD A,E | |||||||||||
| B442 | OR (HL) | |||||||||||
| B443 | XOR D | |||||||||||
| B444 | LD (HL),A | |||||||||||
|
Move up to the start of the previous row of the buffer.
|
||||||||||||
| B445 | LD A,L | Subtract the number of bytes to step back (the operand of this instruction is modified) from the low byte of the buffer address. | ||||||||||
| B446 | SUB $00 | |||||||||||
| B448 | LD L,A | Keep the result. | ||||||||||
| B449 | JP NC,DrawSprite_Aligned_Next | Take a carry from the high byte if there was a borrow. | ||||||||||
| B44C | DEC H | |||||||||||
| DrawSprite_Aligned_Next | B44D | EXX | Switch to the shadow registers, where B' holds the number of rows left to draw. | |||||||||
| B44E | DJNZ DrawSprite_Aligned_Row | Loop back until every row of the sprite has been drawn. | ||||||||||
| B450 | JP DrawSprite_Done | Jump to DrawSprite_Done. | ||||||||||
| Prev: B294 | Up: Map | Next: B453 |