;------------------------------------------------------------------------------- ;@doc:file ; ; === Rectangle.asm === ; ; Provides methods for drawing rectangles. ; ;@doc:end ;------------------------------------------------------------------------------- .module Rectangle ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Rectangle.PlotFill === ; ; Fills a rectangle from a PLOT command. ; ; INPUTS: ; MEMORY ; * Graphics.VisitedPoints - The two most recently visited points define ; - corners of the rectangle. ; * Graphics.CurrentColour - The colour of the rectangle. ; ; DESTROYED: ; REGISTERS ; * AF, BC, DE, HL. ; MEMORY ; * OP1 ; ;@doc:end ;------------------------------------------------------------------------------- PlotFill ; Cull X ld hl,(Graphics.VisitedPoint0.X) call Graphics.ScaleX.HL ld de,(Graphics.VisitedPoint1.X) call Graphics.ScaleX.DE push hl push de cp_shlde() pop de pop hl jr c,+ ex de,hl + ld (OP1+0),hl ; X1 ld (OP1+2),de ; X2 ; X2 < MinX? ld hl,(Graphics.Bounds.MinX) ld h,0 ex de,hl cp_shlde() ret c ; X1 > MaxX? (MaxX < X1) ld de,(OP1+0) ld hl,(Graphics.Bounds.MaxX) ld h,0 cp_shlde() ret c ; Cull Y ld hl,(Graphics.VisitedPoint0.Y) call Graphics.ScaleY.HL call Graphics.FlipY16 ld d,h ld e,l ld hl,(Graphics.VisitedPoint1.Y) call Graphics.ScaleY.HL call Graphics.FlipY16 push hl push de cp_shlde() pop de pop hl jp c,+ ex de,hl + ld (OP1+4),hl ; Y1 ld (OP1+6),de ; Y2 ; Y2 < MinY? ld hl,(Graphics.Bounds.MinY) ld h,0 ex de,hl cp_shlde() ret c ; Y1 > MaxY? (MaxY < Y1) ld de,(OP1+4) ld hl,(Graphics.Bounds.MaxY) ld h,0 cp_shlde() ret c ; Clip to viewport. ld de,(Graphics.Bounds+0) ; MinX~MaxX ld hl,(OP1+0) call Graphics.Clip16 ld (TopLeft.X),a ld hl,(OP1+2) call Graphics.Clip16 ld (BottomRight.X),a ld de,(Graphics.Bounds+2) ; MinY~MaxY ld hl,(OP1+4) call Graphics.Clip16 ld (TopLeft.Y),a ld hl,(OP1+6) call Graphics.Clip16 ld (BottomRight.Y),a .fcall "Graphics.PlotUpdateColours" .fcall "Graphics.SetPatternBuffer" call Fill8 ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Rectangle.Clear === ; ; Clears the graphics device to the current background colour. ; ; DESTROYED: ; REGISTERS ; * AF, BC, DE, HL. ; ;@doc:end ;------------------------------------------------------------------------------- Clear ld a,(Graphics.BackgroundColour) ld (Graphics.CurrentColour),a ld a,(Bounds+0) \ ld (TopLeft.X),a ld a,(Bounds+1) \ ld (BottomRight.X),a ld a,(Bounds+2) \ ld (TopLeft.Y),a ld a,(Bounds+3) \ ld (BottomRight.Y),a call Graphics.SetPatternBuffer ; Deliberate run-on. ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Rectangle.Fill8 === ; ; Fills a rectangle using 8-bit coordinates. ; ; DESTROYED: ; REGISTERS ; * AF, BC, DE, HL. ; ;@doc:end ;------------------------------------------------------------------------------- Fill8 push ix ex af,af' push af ex af,af' ; What's the plot mode? ld hl,(ColumnPlotRoutine) rst rMov9ToOP1 ld hl,PatternBuffer ld a,(TopLeft.Y) ; Y Min and 7 ld (PatternBufferOffsetStart),a ld e,a ld d,0 add hl,de ld (PatternBufferStart),hl ld a,(TopLeft.Y) ; Y Min ld b,a ld a,(BottomRight.Y) ; Y Max sub b inc a ld (RowsToFill),a ld c,a ; c = number of rows to fill. ld a,(TopLeft.Y) ; Y Min add a,a ; * 2 add a,a ; * 4 ld h,0 ld l,a ld d,h ld e,l add hl,hl ; * 8 add hl,de ; * 12 ld de,(Lcd.Buffer) add hl,de ; hl->row to start clearing. ld a,(TopLeft.X) ; X Min add a,7 srl a srl a srl a ld e,a ; e = offset to first *whole* column to clear. ld a,(BottomRight.X) ; X Max inc a srl a srl a srl a ; a = offset to last *whole* column to clear + 1. sub e jr z,NoWholeColumnsToFill cp -1 jr z,NoWholeColumnsToFill ld b,a ; b = number of whole columns to fill. di push hl ld d,0 add hl,de ld de,12 ld ix,(PatternBufferStart) ex af,af' ld a,(PatternBufferOffsetStart) ex af,af' -- push hl push bc ld c,(ix) call OP1 pop bc pop hl add hl,de ; +12 ; Increment pattern buffer pointer (and wrap). ex af,af' inc ix inc a and 7 jr nz,+ ld ix,PatternBuffer + ex af,af' dec c jr nz,-- pop hl ei NoWholeColumnsToFill push hl ld hl,(CapPlotRoutine) ld de,OP1 ld bc,11 ldir pop hl ; Now we've filled any whole columns that needed filling, ; we need to fill the partial edges at the left and right of the screen. ld a,(TopLeft.X) srl a srl a srl a ld (LeftOffset),a ld b,a ld a,(BottomRight.X) srl a srl a srl a ld (RightOffset),a cp b jr z,BothCapsInSameByte ; Left needs capping? call CalcLeftCap \ inc d jr z,NoCapLeft ; Need to cap left push hl ld de,(LeftOffset) ld d,0 add hl,de ld a,(LeftCap) call CapClearLines pop hl NoCapLeft ; Right needs capping? call CalcRightCap \ inc d jr z,CappedClearLines ; Need to cap right push hl ld de,(RightOffset) ld d,0 add hl,de ld a,(RightCap) call CapClearLines pop hl jr CappedClearLines BothCapsInSameByte ; Hrm. call CalcLeftCap call CalcRightCap ld a,(LeftCap) and d cp $FF jr z,CappedClearLines ld (LeftCap),a ld de,(LeftOffset) ld d,0 add hl,de ld a,(LeftCap) call CapClearLines CappedClearLines ld a,(Vdu.WriteToLcdEnabled) or a call nz,Copy ex af,af' pop af ex af,af' pop ix ret CapClearLines di ld d,a ; d = AND mask with pattern. cpl ld c,a ; c = AND mask with background. ld a,(RowsToFill) ld b,a ex af,af' ld a,(PatternBufferOffsetStart) ld ix,(PatternBufferStart) ex af,af' - call OP1 ex af,af' inc ix inc a and 7 jr nz,+ ld ix,PatternBuffer + ex af,af' push de ld de,12 add hl,de pop de djnz - ei ret CalcLeftCap ld a,(TopLeft.X) ; Left edge. and 7 ld d,$FF jr z,+ ld b,a - srl d djnz - + ld a,d ld (LeftCap),a ret CalcRightCap ld a,(BottomRight.X) ; Right edge and 7 neg add a,7 ld d,$FF jr z,+ ld b,a - sla d djnz - + ld a,d ld (RightCap),a ret .endmodule