Prev: DB1F Up: Map Next: DBF5
DB98: Draw/erase graphics - screen boundary checks
Used by the routines at C03F, D27D, D446, D4B2, DA4D, E46C, E987 and E9DD.
Input
HL Address pointer for graphics to draw, from address pointer table at 97C3
The first check is to see if the item's horizontal/vertical pixel co-ordinates fall within the bounds of the visible playing area.
The checks also test for cases where part of the graphic is on-screen - it's only considered 'off-screen' if none of it needs drawing.
DB98 LD E,(HL) Transfer the address (from 97C3) pointed to by HL into the DE register
DB99 INC HL
DB9A LD D,(HL)
DB9B EX DE,HL Swap back so HL now points to the graphics data, e.g. 9950
DB9C LD A,$00 This is the flag indicating whether (any part of) the graphic is visible on-screen (0 = not visible, 1 = visible)
It'll be updated shortly once we've worked out if any part of the graphic is on-screen or not
DB9E LD ($EAD5),A This is set to not visible (0) for off-screen objects, but if any part of the item needs drawing, it's set to 1 (visible) at DBF5
DBA1 LD A,(HL) Number of tiles that make up the graphic/sprite
DBA2 LD ($EAD0),A ...and store...
DBA5 INC HL HL now at the start of the graphic's first tile data
This entry point is used by the routine at DC77.
DBA6 LD C,(HL) Store this byte in C register. This is the horizontal pixel offset for drawing this tile from its screen X/Y co-ordinates
DBA7 INC HL Move onto the next byte
DBA8 EX DE,HL Swap the graphics address pointer back into the DE register
Calculate horizontal (X) pixel offset, check for out of bounds
DBA9 LD HL,($EAD3) Get graphic X horizontal (pixel) position from character column 1 on the left of the screen (the right hand part of the left border).
DBAC LD A,C Graphic's horizontal offset in pixels
DBAD RLA If the offset is >=128, it's a negative pixel offset (e.g. 253 = -3 pixels)
DBAE SBC A,A ...So if the RLA creates a carry, the SBC will set A to to 255 (-1). Otherwise 0.
DBAF LD B,A Transfer to B. This determines if the offset value gets subtracted or added in the next instruction.
DBB0 ADD HL,BC Add horizontal pixel offset to horizontal pixel drawing position
DBB1 EX DE,HL Swap into DE
DBB2 LD A,D Get the high byte of the horizontal position as just calculated
DBB3 CP $00 If high byte changed from 0 to 1, the graphic has gone out of the screen's viewport boundary
DBB5 JP NZ,$DC77 ...if so, skip out of this routine to deal with the out-of-bounds graphic
DBB8 LD A,E Get horizontal pixel position
DBB9 CP $E8 Check to see if this is in the right hand border screen position - 232/8 = 29, but as the counting starts at pixel column 8 (character column 1, rather than 0), this will be character column 30 in the right hand border
DBBB JP NC,$DC77 If there's no carry, jump out of this routine to deal with the out-of-bounds graphic
DBBE ADD A,$08 The screen display address is calculated (in the next routine) from the leftmost screen column - i.e. column 0, not column 1 as currently stored - so add 8 so that this is taken into account.
DBC0 LD E,A Store in E register ready for the next part of the routine at DBF5
DBC1 AND $07 Take lowest 3 bits (values 0-7)
DBC3 LD B,A Store in B register - this is the number of pixel shifts needed for the graphic at DC32
Calculate vertical (Y) pixel offset, check for out of bounds
DBC4 LD A,($EAD2) Get graphic Y vertical (pixel) position, e.g. 80 for character row 10 (80/8)
DBC7 ADD A,(HL) Add to the graphic vertical offset, e.g. an offset of 231 means a -25 vertical pixel offset to the existing co-ordinate
DBC8 INC HL Move HL to the next pre-graphics byte address
DBC9 LD C,(HL) Number of bytes in the next tile graphic
DBCA INC HL HL now points to first graphic tile byte ready for drawing
DBCB CP $70 Vertical pixel position 112 is the top of the scroll, which is out of bounds for drawing graphics
DBCD JP C,$DBEA Carry means (at least the top part of) the item is within the screen viewport and drawable, so jump to DBEA
A no-carry indicates the vertical-pixel-position-plus-offset is either above the top of the playing area or into the scroll area.
However, some part of the item may be visible; for example the vertical corner floor/wall connectors can be partly off the top of the playing area, but the rest of them may be visible on-screen.
DBD0 LD D,A Store vertical (Y) pixel position
DBD1 ADD A,C Add the number of bytes in the tile to the current out-of-bounds position
DBD2 JP NC,$DC7A
DBD5 JP Z,$DC7A A no-carry or zero result means that no part of the object is visible, so this graphic doesn't need drawing. Jump out here to re-calculate address pointers etc.
Some (lower) part of this graphic is visible at the top of the screen. Put the graphics address pointer to the right part of the graphics and set the pixel row number in the line.
DBD8 LD ($EAD1),A Store the number of bytes in the visible part of the graphic tile left to draw
DBDB LD A,D Retrieve the vertical pixel co-ordinate (plus offset). This will be a negative number...
DBDC NEG So make it positive...
DBDE ADD A,L HL is pointing at the address for the tile graphics...
DBDF LD L,A
DBE0 LD A,$00
DBE2 ADC A,H ...So increase it by the number of bytes that don't need to be drawn as they're in/above the decorative border
DBE3 LD H,A
DBE4 LD D,$10 Set the vertical screen position to 16 pixel rows down - the first byte of character row 2, just below the top border
DBE6 LD C,$00 C register contains the pixel row; as we're starting from character row 2 means that the first byte will be pixel row 0
DBE8 JR $DBF5 Ready to calculate screen address low/high bytes
Jump from DBCD. The graphic (or at least the top of it) are drawable. Set the screen vertical pixel position and pixel row in the line (0-7).
DBEA ADD A,$10 Vertical pixel position starts from 0 (16 pixels from top of screen...
DBEC LD D,A D contains vertical Y screen pixel position
DBED LD A,C Get number of tile bytes to draw
DBEE LD ($EAD1),A ...and store...
DBF1 LD A,D Get A back from D (mystery value - now 71)
DBF2 AND $07 Take lowest 3 bits (0,1,2) - pixel row number in line
DBF4 LD C,A Store in C register for the next part of the routine
Prev: DB1F Up: Map Next: DBF5