Prev: D161 Up: Map Next: D1D2
D179: Tunnel position & direction
Used by the routine at C89F.
The first byte in the data sets (7C00) for tunnels has the ID number of 15, which is the general tunnel position and direction.
The other tunnel elements - walls/boundaries, spiders and bats - are dealt with separately in the same way as room objects.
D179 LD A,$00
D17B LD ($EB4A),A Set vertical pixel position to 0 (top of screen)
The game timer is used to generate actions such as changing the tunnel direction, spiders, bats etc.
Every 16th cycle of the game timer, a new tunnel direction is calculated:
D17E LD A,($EAAA) Get incremental game timer
D181 AND $0F Check if any of bits 0-3 are set
D183 JR NZ,$D1B5 If so, continue the tunnel. The number bit value in the AND instruction acts as an interval that affects tunnel duration. It can be changed for shorter tunnels - see the POKEs section.
Check if Maroc has reached the end of the tunnel
D185 LD A,($EB7D) Get tunnel length counter (first byte of tunnel data sets at 6710 multiplied by 2)
D188 DEC A ...decrement it..
D189 LD ($EB7D),A ...and re-store
D18C JR NZ,$D193 Interval check - has Maroc reached the end of the tunnel?
D18E LD A,$FF ...If so, set the 'end-of-tunnel' byte accordingly - this is checked at DA1D and indicates that the new room number at the end of the tunnel will need evaluating/setting.
D190 LD ($EAB0),A
Determine left/right direction, and offset, of tunnel walls. Bytes in ROM are used to randomize direction.
Tunnel horizontal position can change left or right between -31 and +31 pixels. If the byte value is outside these values (32 - 224) the current offset is not changed, i.e. the tunnel continues in the same direction without changing.
D193 LD HL,($EB44) Value used to address various ROM locations to generate pseudo-random numbers for tunnels
D196 INC HL Move to the next ROM address
D197 LD ($EB44),HL ..and re-store pointer
D19A LD A,(HL) Get byte from ROM address
D19B AND $3F Keep a range of 0-63
D19D SUB $1F Subtract 31, giving a value of +32 to -31
D19F LD C,A Put in C register
D1A0 LD A,($EB4C) Get the current horizontal offset byte
D1A3 ADD A,C Add or subtract the direction change offset (+32 to +31)
D1A4 CP $80 Check if byte value is >= 128 (bit 7 set)
D1A6 JR NC,$D1AE
D1A8 CP $20 If not, check if byte value >= 32
D1AA JR NC,$D1B5 If so, it's outside the threshold so jump straight to D1B5 (don't change horizontal offset value)
D1AC JR $D1B2
D1AE CP $E0 Byte value is > 128 so check if value < 224
D1B0 JR C,$D1B5 If so, it's outside the threshold so jump straight to D1B5 (don't change horizontal offset value)
D1B2 LD ($EB4C),A Byte value is OK - store the new horizontal offset value
If the tunnel's horizontal position is too close to the left or right edge of the screen, shift its direction slightly back towards the centre:
D1B5 LD A,($EB48) Horizontal position (in 4-pixel/half-character steps)
D1B8 LD ($EC9E),A Copy to item horizontal position data store
D1BB LD C,A Temp store in C
D1BC SUB $10 If we subtract 16...
D1BE CP $20 ...and check against 32...
D1C0 JR C,$D1CF ...a carry (jump to the end of the routine) will occur if the boundary is between 16 half-character steps and 48 half-character steps (this is OK)
D1C2 LD A,$1C Otherwise, subtract the horizontal position from 28 (roughly centre of screen)
D1C4 SUB C
D1C5 SRA A ...and halve the offset, bringing it slightly closer to the centre of the screen
D1C7 LD ($EB4C),A Re-store as the new horizontal position
D1CA NEG Maroc's offset is the opposite of the scenery
D1CC LD ($EB04),A ...So store the negative of this value for his horizontal offset.
D1CF JP $D27D
Prev: D161 Up: Map Next: D1D2