Prev: BF41 Up: Map Next: C0E1
BFA5: Draw Object
Used by the routine at DrawGroupObjects.
Prepares an object of a group for drawing, and then passes it to the routine whose address is the operand of the JP at C0DE which is set by DrawLevelObjects. It works out the screen column and row of the object, and returns without doing anything if the object is not in view. Objects that can be entities are passed to AddObjectEntity first, and an object that has the flag for it in the row of flags of the group is also given an item record with AddItemRecord.
Input
IX The object, which is three bytes
Work out the screen column of the object. This is the depth of the cell plus the sum of the two halves of the first byte of the object, which are its offsets along the x and y axes, less the origin of the view.
DrawObject BFA5 LD H,$00 Set H to the depth of the cell, which is patched in.
BFA7 LD A,(IX+$00) Fetch the first byte of the object.
BFAA ADD A,A Multiply it by sixteen, to move the offset along the y axis to the top four bits...
BFAB ADD A,A
BFAC ADD A,A
BFAD ADD A,A
BFAE LD E,A ...and keep it in E.
BFAF LD A,(IX+$00) Fetch the first byte of the object again.
BFB2 AND %11110000 Keep the offset along the x axis in the top four bits.
BFB4 ADD A,E Add the two offsets to find the low byte of the screen column.
BFB5 JR NC,DrawObject_SetColumn Jump to DrawObject_SetColumn if there was no carry.
BFB7 INC H Increase the high byte of the screen column.
DrawObject_SetColumn BFB8 LD L,A Put the low byte of the screen column in L.
BFB9 LD BC,$0000 Set BC to the origin of the view, which is patched in.
BFBC ADD HL,BC Add the origin to the screen column.
Find out whether the object can be an entity. Objects of kind 81 and 8F are passed to AddObjectEntity, and any other kind is drawn straight away.
BFBD LD A,(IX+$01) Fetch the second byte of the object.
BFC0 AND %10001111 Keep bit 7 and the kind in bits 0-3.
BFC2 CP $81 Jump to DrawObject_Entity if it is kind 81.
BFC4 JR Z,DrawObject_Entity
BFC6 BIT 7,A Jump to DrawObject_Position if bit 7 is not set.
BFC8 JP Z,DrawObject_Position
BFCB INC A Add one to the kind.
BFCC AND %00001111 Keep the kind.
BFCE JP NZ,DrawObject_Position Jump to DrawObject_Position unless the kind was 8F.
DrawObject_Entity BFD1 LD B,(IX+$02) Fetch the third byte of the object into B...
BFD4 LD C,(IX+$01) ...and the second byte into C.
BFD7 PUSH BC Save them.
BFD8 PUSH HL Save the screen column.
BFD9 LD A,C Copy the second byte into A.
BFDA AND %10001111 Keep bit 7 and the kind.
BFDC CP $8F Jump to DrawObject_Add if it is kind 8F, so that the bytes are used as they are.
BFDE JR Z,DrawObject_Add
Change an object of kind 81 into an object of kind 8F that has the size of the object in its third byte, so that it is recorded with that size.
BFE0 LD A,B Fetch the third byte of the object.
BFE1 RRA Shift the size in bits 4-5 to bits 2-3...
BFE2 RRA
BFE3 AND %00110000 ...and keep it.
BFE5 ADD A,$10 Add 10.
BFE7 LD B,A Keep it in B.
BFE8 LD A,C Fetch the second byte of the object.
BFE9 AND %01110000 Keep the height in bits 4-6.
BFEB ADD A,B Add the size to the height.
BFEC LD (IX+$02),$01 Set the third byte of the object to 01.
BFF0 CP $80 Jump to DrawObject_SetKind if it is below 80.
BFF2 JR C,DrawObject_SetKind
BFF4 SUB $80 Take away 80.
BFF6 SET 6,(IX+$02) Set bit 6 of the third byte of the object.
DrawObject_SetKind BFFA OR %10001111 Set bits 0-3 and bit 7, to make it kind 8F.
BFFC LD (IX+$01),A Store it as the second byte of the object.
DrawObject_Add BFFF CALL AddObjectEntity Add an entity for the object, if it has one, and record it.
C002 POP HL Restore the screen column.
C003 POP BC Restore the second and third bytes of the object...
C004 LD (IX+$01),C ...and put them back.
C007 LD (IX+$02),B Put the third byte back.
C00A LD A,C Fetch the second byte of the object.
C00B AND %10001111 Keep bit 7 and the kind.
C00D CP $8F Compare it with 8F.
C00F RET Z Return if it is kind 8F as it is an entity and is not drawn as a block.
C010 LD A,(IX+$00) Fetch the first byte of the object.
C013 ADD A,A Multiply it by sixteen, to move the offset along the y axis to the top four bits...
C014 ADD A,A
C015 ADD A,A
C016 ADD A,A
C017 LD E,A ...and keep it in E.
Check that the object is not off the left of the view, or off the right of it, using the width of the object.
DrawObject_Position C018 LD A,L Fetch the low byte of the screen column.
C019 AND %11111000 Round it down to a multiple of eight.
C01B LD L,A Put it back.
C01C PUSH HL Save the screen column.
C01D BIT 7,H Jump to DrawObject_Far if bit 7 of the high byte of the screen column is set.
C01F JR NZ,DrawObject_Far
C021 LD B,$00 Clear B.
C023 LD C,(IX+$02) Fetch the third byte of the object into C.
C026 SLA C Double it.
C028 LD A,C Copy it into A.
C029 AND %01110000 Keep the width in bits 4-6.
C02B LD D,A Keep it in D.
C02C LD A,C Fetch the doubled byte again.
C02D ADD A,A Shift it left three times, to move the depth to bits 4-6...
C02E ADD A,A
C02F ADD A,A
C030 AND %01110000 ...and keep it.
C032 ADD A,D Add the width.
C033 ADD A,$1F Add 1F to make the distance to the left of the object.
C035 LD C,A Put it in C.
C036 ADD HL,BC Add it to the screen column.
C037 INC HL Move on by one more.
C038 RL H Rotate bit 7 of the high byte into the carry flag.
C03A POP HL Restore the screen column.
C03B RET NC Return if the object is off the left of the view.
C03C JR DrawObject_Visible Jump to DrawObject_Visible.
DrawObject_Far C03E LD BC,$80C0 BC is 80C0 the right edge of the view.
C041 SBC HL,BC Subtract it from the screen column.
C043 POP HL Restore the screen column.
C044 RET NC Return if the object is off the right of the view.
Work out the screen row of the object. This is half of the difference between its x and y coordinates, plus the offset to the view, less the height of the object.
DrawObject_Visible C045 LD ($BB9F),HL Store the screen column, as the one to draw at.
C048 LD A,($5CBA) Fetch the row of the cell into D.
C04B LD D,A Keep the y coordinate of the cell...
C04C LD HL,($5CB8) Fetch the column of the cell into H.
C04F LD A,(IX+$00) Fetch the first byte of the object.
C052 AND %11110000 Keep the offset along the x axis.
C054 LD L,A Make it the low byte of the x coordinate.
C055 SRL D Halve the y coordinate...
C057 RR E
C059 SRL H ...and halve the x coordinate.
C05B RR L
C05D AND A Subtract half of the y coordinate from half of the x coordinate.
C05E SBC HL,DE
C060 LD DE,$0000 Set DE to the offset to the view, which is patched in.
C063 ADD HL,DE Add the offset.
C064 LD A,(IX+$01) Fetch the second byte of the object.
C067 AND %01110000 Keep the height in bits 4-6.
C069 LD E,A Keep it in E.
C06A LD A,(IX+$01) Fetch the second byte of the object again.
C06D AND %10001111 Keep bit 7 and the kind.
C06F CP $83 Jump to DrawObject_AddHeight if it is kind 83.
C071 JR Z,DrawObject_AddHeight
C073 CP $85 Jump to DrawObject_SubtractHeight unless it is kind 85.
C075 JR NZ,DrawObject_SubtractHeight
DrawObject_AddHeight C077 LD A,$10 A is 10 which is added to the height of these kinds.
C079 ADD A,E Add the height.
C07A LD E,A Keep it in E.
DrawObject_SubtractHeight C07B LD D,$00 Clear D.
C07D AND A Subtract the height from the screen row.
C07E SBC HL,DE
C080 PUSH HL Save the screen row.
Check that the object is not above the view.
C081 LD A,(IX+$02) Fetch the third byte of the object.
C084 ADD A,A Shift it left three times, to move the depth to bits 3-5...
C085 ADD A,A
C086 ADD A,A
C087 AND %00111000 ...and keep it.
C089 ADD A,$08 Add 08.
C08B LD E,A Keep it in E.
C08C ADD HL,DE Add it to the screen row.
C08D RL H Rotate bit 7 of the high byte into the carry flag.
C08F POP HL Restore the screen row.
C090 RET NC Return if the object is above the view.
Check that the object is not below the view, and work out the height of the object.
C091 PUSH HL Save the screen row.
C092 LD A,(IX+$02) Fetch the third byte of the object and keep it in B.
C095 LD B,A
C096 AND %00111000 Keep the depth in bits 3-5.
C098 ADD A,$08 Add 08.
C09A LD E,A Keep it in E.
C09B LD A,(IX+$01) Fetch the second byte of the object.
C09E BIT 7,A Jump to DrawObject_SizeFromByte if bit 7 is set.
C0A0 JR NZ,DrawObject_SizeFromByte
C0A2 AND %00001111 Keep the kind.
C0A4 SUB $02 Take away 02.
C0A6 JR Z,DrawObject_StoreHeight Jump to DrawObject_StoreHeight if it is kind 02 with zero as the size.
DrawObject_SizeFromByte C0A8 LD A,B Fetch the third byte of the object.
C0A9 RRA Shift the size in bits 4-5 to bits 2-3...
C0AA RRA
C0AB AND %00110000 ...and keep it.
C0AD ADD A,$10 Add 10.
DrawObject_StoreHeight C0AF LD ($5CF5),A Store it as the height of the object, in 5CF5.
C0B2 ADD A,E Add the depth.
C0B3 LD E,A Keep it in E.
C0B4 SBC HL,DE Subtract it from the screen row.
C0B6 LD DE,$8080 DE is 8080 the bottom of the view.
C0B9 SBC HL,DE Subtract it from the screen row.
C0BB POP HL Restore the screen row.
C0BC RET NC Return if the object is below the view.
C0BD LD ($BBA1),HL Store the screen row, as the one to draw at.
Work out the depth and the width of the object, and store them.
C0C0 LD A,(IX+$02) Fetch the third byte of the object.
C0C3 ADD A,A Double it...
C0C4 LD B,A ...and keep it in B.
C0C5 AND %01110000 Keep the size in bits 4-6.
C0C7 ADD A,$10 Add 10.
C0C9 LD ($5CF4),A Store it as the depth of the object, in 5CF4.
C0CC LD A,B Fetch the doubled byte again.
C0CD ADD A,A Shift it left three times, to move the other size to bits 4-6...
C0CE ADD A,A
C0CF ADD A,A
C0D0 AND %01110000 ...and keep it.
C0D2 ADD A,$10 Add 10.
C0D4 LD ($5CF3),A Store it as the width of the object, in RecordDetails.
Give the object an item record if its flag in the row of flags of the group is set, and then pass it to the routine that handles it.
C0D7 LD A,($BB8F) Fetch the first byte of the row of flags of the group.
C0DA RLA Rotate its top bit into the carry flag.
DrawObject_Record C0DB CALL C,AddItemRecord Add an item record for the object if the flag is set.
DrawObject_Handle C0DE JP DrawObject_Handle Jump to the routine that handles the object, which is patched in.
Prev: BF41 Up: Map Next: C0E1