Prev: E18C Up: Map Next: E272
E1B4: Check Bubble Contact
Checks whether an object is touching one of the four bubbles (the object records that start at First_Bubble_Record and have the type 58 to 5B).
No bubble is touched if bit 4 or bit 5 of the countdown in byte 0A is set. This is the case for Sabreman for a while after he has started to fall, and it lets him get away from a bubble.
An object touches a bubble when the two are in the same room, the x positions differ by less than 0D and the y position of the object is between zero and 0E pixels above the y position of the bubble.
When there is contact the result in C has bit 2 and bit 1 set (a bubble is always taken as being under the object). Bit 7 is set if the object is to the right of the bubble. Bits 5 and 0 are set if the x positions differ by 0A or more, which means that the object is not near the middle of the bubble. Otherwise the y position of the object is set to 0E less than that of the bubble so that it stands on it, and bit 4 of E and bit 4 of the contact flags (byte 0B) are set.
If the object is Sabreman (the type is between 09 and 1B) and he is touching a bubble while he is near the top of the room (the y position is less than 48) then the bubble pushes him up. In a room with a ceiling he starts tumbling (see Start_Tumbling_Downwards), which draws him and ends the handler that called this routine. In a room with no ceiling he moves into the room above, if his y position is less than 2C. The y position then becomes AF the first bubble record becomes a copy of the record of Sabreman as a bubble (58) at the y position B8 and the new room is drawn.
Input
IX Object record
E Flags of the room (see Read_World_Map)
Output
B A0 less the y position of the object (valid when there is contact)
C Contact result
E Flags of the room, with bit 4 set if the object stands on a bubble
Check_Bubble_Contact E1B4 LD C,$00 Set the contact result to zero.
E1B6 LD A,(IX+$0A) Fetch the countdown.
E1B9 AND %00110000 Keep only bits 4 and 5.
E1BB RET NZ Return if either of them is set.
E1BC PUSH DE Stash the flags of the room.
E1BD LD HL,$8F5A Point HL at First_Bubble_Record.
E1C0 LD DE,$0010 Set DE to the size of an object record.
E1C3 LD B,$04 Set a counter in B for the four bubble records.
Check_Bubble_Contact_Loop E1C5 LD A,(HL) Fetch the type of the record.
E1C6 AND %11111100 Ignore the two low bits.
E1C8 CP $58 Jump to Check_Bubble_Contact_Found if the record holds a bubble.
E1CA JR Z,Check_Bubble_Contact_Found
Check_Bubble_Contact_Next_Record E1CC ADD HL,DE Move on to the next record.
E1CD DJNZ Check_Bubble_Contact_Loop Decrease the record counter and loop back for the next record.
E1CF LD C,$00 Clear the contact result, as no bubble was touched.
E1D1 POP DE Restore the flags of the room.
E1D2 RET Return.
Check_Bubble_Contact_Skip E1D3 POP HL Discard the address of the bubble record.
E1D4 JR Check_Bubble_Contact_Next_Record Jump to Check_Bubble_Contact_Next_Record to try the next bubble.
Check_Bubble_Contact_Found E1D6 PUSH HL Stash the address of the bubble record.
E1D7 LD C,$00 Clear the contact result.
E1D9 INC HL Point HL at the x position of the bubble.
E1DA LD A,(HL) Fetch the x position of the bubble.
E1DB SUB (IX+$01) Jump to Check_Bubble_Contact_Check_Width if the object is not to the right of the bubble.
E1DE JP P,Check_Bubble_Contact_Check_Width
E1E1 NEG Make the difference positive.
E1E3 SET 7,C Set bit 7 of the contact result, as the object is to the right of the bubble.
Check_Bubble_Contact_Check_Width E1E5 CP $0D Jump to Check_Bubble_Contact_Skip if the difference is 0D or more.
E1E7 JR NC,Check_Bubble_Contact_Skip
E1E9 CP $0A Jump to Check_Bubble_Contact_Check_Room if the difference is less than 0A.
E1EB JR C,Check_Bubble_Contact_Check_Room
E1ED SET 5,C Set bit 5 of the contact result.
E1EF SET 0,C Set bit 0 of the contact result.
Check_Bubble_Contact_Check_Room E1F1 INC HL Point HL at the room x of the bubble.
E1F2 LD A,(HL) Fetch the room x of the bubble.
E1F3 CP (IX+$02) Jump to Check_Bubble_Contact_Skip if the bubble is in a different room x.
E1F6 JR NZ,Check_Bubble_Contact_Skip
E1F8 INC HL Point HL at the y position of the bubble.
E1F9 LD A,(HL) Fetch the y position of the bubble.
E1FA SUB (IX+$03) Subtract the y position of the object.
E1FD CP $0F Jump to Check_Bubble_Contact_Skip if the object is more than 0E above the bubble, or below it.
E1FF JR NC,Check_Bubble_Contact_Skip
E201 INC HL Point HL at the room y of the bubble.
E202 LD A,(HL) Fetch the room y of the bubble.
E203 CP (IX+$04) Jump to Check_Bubble_Contact_Skip if the bubble is in a different room y.
E206 JR NZ,Check_Bubble_Contact_Skip
E208 DEC HL Point HL at the y position of the bubble again.
E209 SET 2,C Set bit 2 of the contact result (contact).
E20B SET 1,C Set bit 1 of the contact result (the object is on top).
E20D BIT 0,C Jump to Check_Bubble_Contact_Set_Height if the object is not near the middle of the bubble.
E20F JR NZ,Check_Bubble_Contact_Set_Height
E211 LD A,(HL) Fetch the y position of the bubble.
E212 SUB $0E Subtract 0E.
E214 LD (IX+$03),A Set the y position of the object, so that it stands on the bubble.
Check_Bubble_Contact_Set_Height E217 LD A,(IX+$03) Fetch the y position of the object.
E21A SUB $A0 Subtract A0.
E21C NEG Negate it.
E21E LD B,A Store the result in B.
E21F POP HL Discard the address of the bubble record.
E220 POP DE Restore the flags of the room to E.
E221 BIT 0,C Jump to Check_Bubble_Contact_Check_Type if the object is not near the middle of the bubble.
E223 JR NZ,Check_Bubble_Contact_Check_Type
E225 SET 4,E Set bit 4 of the flags of the room (the floor).
E227 SET 4,(IX+$0B) Set bit 4 of the contact flags (standing).
Check_Bubble_Contact_Check_Type E22B LD A,(IX+$00) Fetch the type of the object.
E22E CP $1C Return if the type is 1C or more.
E230 RET NC
E231 CP $09 Return if the type is less than 09.
E233 RET C
E234 LD A,(IX+$03) Fetch the y position of the object.
E237 CP $48 Return if it is 48 or more.
E239 RET NC
E23A BIT 0,E Jump to Check_Bubble_Contact_Tumble if the room has a ceiling.
E23C JR NZ,Check_Bubble_Contact_Tumble
E23E CP $2C Return if the y position is 2C or more.
E240 RET NC
E241 DEC (IX+$04) Move Sabreman to the room above.
E244 LD (IX+$03),$AF Set his y position to AF.
E248 LD B,$F1 Set B to F1 which is A0 less the new y position.
E24A PUSH DE Stash the flags of the room.
E24B PUSH BC Stash the contact result and B.
E24C LD DE,$8F5A Point DE at First_Bubble_Record.
E24F LD HL,$8F1A Point HL at Sabreman_Record.
E252 LD BC,$000F Set a counter of 0F bytes.
E255 LDIR Copy the record of Sabreman to the bubble record.
E257 LD A,$B8 Set the y position of the bubble to B8.
E259 LD ($8F5D),A Store the y position of the bubble.
E25C LD A,$58 Set the type of the bubble to 58.
E25E LD ($8F5A),A Store the type of the bubble.
E261 LD A,$01 Set the redraw flags of the bubble to 01.
E263 LD ($8F69),A Store the redraw flags of the bubble.
E266 LD A,$46 Set the attribute of the bubble to 46 (yellow).
E268 LD ($8F5F),A Store the attribute of the bubble.
E26B CALL Draw_Room Draw the room.
E26E POP BC Restore the contact result and B.
E26F POP DE Restore the flags of the room.
E270 RET Return.
Check_Bubble_Contact_Tumble E271 POP HL Discard the return address, so that the handler of Sabreman that called this routine stops here.
Prev: E18C Up: Map Next: E272