;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.Plot === ; ; Plots a shape on the screen. ; ; INPUTS: ; MEMORY ; * PlotShape - The shape to plot. ; * VisitedPoint - Graphics operation depends on these points. ; ;@doc:end ;------------------------------------------------------------------------------- Plot ld a,(PlotShape) ld b,a and %11 ret z ; -- Colour 0 = do not draw (move). dec a ld a,(ForegroundColour) ; -- Colour 1 = foreground colour. jr z,+ ld a,(BackgroundColour) ; -- Colour 3 = background colour. + ld (CurrentColour),a PlotColourSet ld a,b srl a ; \_ Bits 0..1 = colour. srl a ; / srl a ; -- Bit 2 = absolute/relative. cp 216 ret nc add a,a ld l,a ld h,0 ld de,PlotVectors add hl,de ld e,(hl) inc hl ld d,(hl) ld hl,ExitPlotCommand push hl push de ret ExitPlotCommand ld a,(Vdu.WriteToLcdEnabled) or a call nz,Graphics.Copy ret PlotVectors .dw DrawLineSolid ; 0....7 = Regular line. .dw DrawLineSolid ; 8...15 = Regular line (draw last point twice). .dw DrawLineDotted ; 16...23 = Dotted line. .dw DrawLineDotted ; 24...31 = Dotted line (draw last point twice). .dw DrawLineDashed ; 32...39 = Dashed line. .dw DrawLineDashed ; 40...47 = Dashed line (draw last point twice). .dw DrawLineBroken ; 48...55 = Broken line. .dw DrawLineBroken ; 56...63 = Broken line (draw last point twice). .dw PlotSinglePoint ; 64...71 = Single point. .dw Dud ; 72...79 = Horizontal line fill to non-background. .dw PlotTriangle ; 80...87 = Triangle plot and fill. .dw Dud ; 88...95 = Horizontal line fill to background right. .dw Rectangle.PlotFill ; 96..103 = Rectangle plot and fill. .dw Dud ; 104..111 = Horizontal line fill to foreground. .dw PlotParallelogram ; 112..119 = Parallelogram plot and fill. .dw Dud ; 120..127 = Horizontal line fill to non-foreground right. .dw FloodFillNotBack ; 128..135 = Flood fill to non-background. .dw FloodFillFore ; 136..142 = Flood fill to foreground. .dw PlotDrawCircle ; 144..151 = Draw circle. .dw PlotFillCircle ; 152..159 = Draw solid disc. .dw Dud ; 160..167 = Draw circular arc. .dw Dud ; 168..175 = Draw solid segment. .dw Dud ; 176..183 = Draw solid sector. .dw Dud ; 185..191 = Move rectangular block / Copy rectangular block. .dw PlotDrawEllipse ; 192..199 = Draw ellipse. .dw PlotFillEllipse ; 200..207 = Fill ellipse. .dw PlotDrawSprite ; 208..215 = Draw sprite (non-standard, custom extension). Dud ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.DrawLineBroken === ; ; Draws a broken line on the screen. ; ; INPUTS: ; MEMORY ; * VisitedPoint - Line drawn between two most recently visited points. ; ;@doc:end ;------------------------------------------------------------------------------- DrawLineBroken ld hl,$0808 jr DrawLineLoadLineStyle ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.DrawLineDashed === ; ; Draws a dashed line on the screen. ; ; INPUTS: ; MEMORY ; * VisitedPoint - Line drawn between two most recently visited points. ; ;@doc:end ;------------------------------------------------------------------------------- DrawLineDashed ld hl,$0404 jr DrawLineLoadLineStyle ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.DrawLineDotted === ; ; Draws a dotted line on the screen. ; ; INPUTS: ; MEMORY ; * VisitedPoint - Line drawn between two most recently visited points. ; ;@doc:end ;------------------------------------------------------------------------------- DrawLineDotted ld hl,$0101 jr DrawLineLoadLineStyle ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.DrawLineSolid === ; ; Draws a solid line on the screen. ; ; INPUTS: ; MEMORY ; * VisitedPoint - Line drawn between two most recently visited points. ; ;@doc:end ;------------------------------------------------------------------------------- DrawLineSolid ld hl,$0000 DrawLineLoadLineStyle ld (Line.Style),hl DrawLine call PlotUpdateColours ld hl,VisitedPoints rst rMov9ToOP1 ld hl,(OP1+0) call ScaleX.HL ld (OP1+0),hl ld hl,(OP1+2) call ScaleY.HL call FlipY16 ld (OP1+2),hl ld hl,(OP1+4) call ScaleX.HL ld (OP1+4),hl ld hl,(OP1+6) call ScaleY.HL call FlipY16 ld (OP1+6),hl ld hl,OP1+4 ld de,OP1+0 call Clip.Clip2DLine16 ret c call Line.Draw ld a,(PlotShape) bit 3,a jp nz,PlotSinglePoint jp ConditionalCopy ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotSinglePoint === ; ; Plots a single point. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotSinglePoint call GetCurrentCoordinate ret c call PlotIsInverted jr z,PlotSingleInvertedPoint ld a,(CurrentColour) bit 6,a ld a,(PlotMode) jr z,PlotSingleWhitePoint PlotSingleBlackPoint or a jr z,+ ; plot dec a jr z,+ ; or dec a ret z ; and dec a jr z,PlotSingleInvertedPoint + ld a,ixh ld l,b call GetPixelInfo or (hl) ld (hl),a jr PlottedSinglePoint PlotSingleWhitePoint or a jr z,+ ; plot dec a ret z ; or dec a jr z,+ ; and ret + ld a,ixh ld l,b call GetPixelInfo cpl and (hl) ld (hl),a jr PlottedSinglePoint PlotSingleInvertedPoint ld a,ixh ld l,b call GetPixelInfo xor (hl) ld (hl),a PlottedSinglePoint ld a,(Vdu.WriteToLcdEnabled) or a ret z .fcall "Speed.SlowDown" di ; Busy... - in a,(Lcd.InstPort) or a jp m,- ld a,ixl add a,$80 out (Lcd.InstPort),a ; Busy... - in a,(Lcd.InstPort) or a jp m,- ld a,ixh srl a srl a srl a add a,$20 out (Lcd.InstPort),a ; Busy... - in a,(Lcd.InstPort) or a jp m,- ld a,(hl) out (Lcd.DataPort),a .fcall "Speed.SpeedUp" ei ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotTriangle === ; ; Fills a triangle. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotTriangle call Triangle.InitPlotFill jr nc,+ ld hl,Errors.NoRoom .bjump _Host.ReportError + call Triangle.Fill jp ConditionalCopy ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotParallelogram === ; ; Fills a paralellogram. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotParallelogram call Triangle.InitPlotFill jr nc,+ ld hl,Errors.NoRoom .bjump _Host.ReportError + call Triangle.Fill ld hl,(VisitedPoints+ 0) \ call ScaleX.HL \ ld (Triangle.VertexA.X),hl ld hl,(VisitedPoints+ 2) \ call ScaleY.HL \ call FlipY16 \ ld (Triangle.VertexA.Y),hl ld hl,(VisitedPoints+ 8) \ call ScaleX.HL \ ld (Triangle.VertexC.X),hl ld hl,(VisitedPoints+10) \ call ScaleY.HL \ call FlipY16 \ld (Triangle.VertexC.Y),hl ld hl,(VisitedPoints+ 0) ; 3.X ld de,(VisitedPoints+ 4) ; 2.X or a sbc hl,de ld de,(VisitedPoints+ 8) ; 1.X add hl,de call ScaleX.HL ld (Triangle.VertexB.X),hl ld hl,(VisitedPoints+ 2) ; 3.Y ld de,(VisitedPoints+ 6) ; 2.Y or a sbc hl,de ld de,(VisitedPoints+10) ; 1.Y add hl,de call ScaleY.HL call FlipY16 ld (Triangle.VertexB.Y),hl call Triangle.Fill jp c,ConditionalCopy ; Triangle was culled, so do not bother with the next bit. call PlotIsInverted jp nz,ConditionalCopy ; Hack ld hl,(VisitedPoints+ 0) \ call ScaleX.HL \ ld (Triangle.VertexA.X),hl ld hl,(VisitedPoints+ 2) \ call ScaleY.HL \ call FlipY16 \ ld (Triangle.VertexA.Y),hl ld hl,(VisitedPoints+ 8) \ call ScaleX.HL \ ld (Triangle.VertexC.X),hl ld hl,(VisitedPoints+10) \ call ScaleY.HL \ call FlipY16 \ ld (Triangle.VertexC.Y),hl push iy ld iy,(TIOS.IY) ld hl,(Triangle.Edges) ld (Triangle.TraceEdgeOutputA),hl ld de,64 add hl,de ld (Triangle.TraceEdgeOutputB),hl ld hl,(Triangle.VertexC.Y) ld de,(Triangle.VertexA.Y) or a sbc hl,de bit 7,h ld hl,Triangle.VertexA ld de,Triangle.VertexC jr z,+ ex de,hl + ld a,63 ld (Triangle.TopOfTriangle),a xor a ld (Triangle.BottomOfTriangle),a call Triangle.TraceEdge pop iy ld hl,(Triangle.Edges) ld de,128 add hl,de ex de,hl ld hl,(Triangle.Edges) ld bc,128 ldir ld hl,(Triangle.Edges) ld bc,128 ldir call Triangle.Fill.AlreadyTraced jp ConditionalCopy ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotDrawCircle === ; ; Draws a circle. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotDrawCircle push iy ld iy,(TIOS.IY) res fFillEllipse,(iy+ellipseFlags) jr PlotCircle ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotFillCircle === ; ; Fills a circle. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotFillCircle push iy ld iy,(TIOS.IY) set fFillEllipse,(iy+ellipseFlags) call SetPatternBuffer PlotCircle call PlotUpdateColours ; Centre = point visited one MOVE command ago. ld de,(VisitedPoint1.X) call ScaleX.DE ld (g_ellipseCX),de ld hl,(VisitedPoint1.Y) push hl call ScaleY.HL call FlipY16 ld (g_ellipseCY),hl pop hl ld de,(VisitedPoint0.Y) or a sbc hl,de jr nz,PlotCircle.NonZeroHeight ; Height of circle = 0. ld hl,(VisitedPoint1.X) ld de,(VisitedPoint0.X) or a sbc hl,de jp p,+ dec hl ld a,h \ cpl \ ld d,a ld a,l \ cpl \ ld e,a jr FoundCircleRadius + ex de,hl jr FoundCircleRadius PlotCircle.NonZeroHeight jp p,+ dec hl ld a,h \ cpl \ ld b,a ld a,l \ cpl \ ld c,a jr ++ + ld b,h ld c,l ++ push bc ld hl,(VisitedPoint1.X) ld de,(VisitedPoint0.X) or a sbc hl,de jr nz,PlotCircle.NonZeroWidth ; Width of circle = 0. pop bc ld d,b ld e,c jr FoundCircleRadius PlotCircle.NonZeroWidth jp p,+ dec hl ld a,h \ cpl \ ld b,a ld a,l \ cpl \ ld c,a jr ++ + ld b,h ld c,l ++ call SquareBC ; HL:DE = BC*BC pop bc push hl push de call SquareBC ; HL:DE = BC*BC ex de,hl pop bc add hl,bc jr nc,+ inc de + ex de,hl pop bc add hl,bc ; HL:DE = (dx*dx)+(dy*dy) call Maths.Sqr32 ; DE = SQR(HL:DE) FoundCircleRadius ld h,d \ ld l,e .fcall "Graphics.ScaleX.HL" ld (g_ellipseRX),hl .fcall "Graphics.ScaleY.DE" ld (g_ellipseRY),de call DrawEllipse pop iy ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotDrawEllipse === ; ; Draws an ellipse. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotDrawEllipse push iy ld iy,(TIOS.IY) res fFillEllipse,(iy+ellipseFlags) jr PlotEllipse ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotFillEllipse === ; ; Fills an ellipse. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotFillEllipse push iy ld iy,(TIOS.IY) set fFillEllipse,(iy+ellipseFlags) call SetPatternBuffer PlotEllipse call PlotUpdateColours ; Centre = point visited two MOVE commands ago. ld de,(VisitedPoints+8) call ScaleX.DE ld (g_ellipseCX),de ld hl,(VisitedPoints+10) ld b,h \ ld c,l call ScaleY.HL call FlipY16 ld (g_ellipseCY),hl ; Width = second position visited. ld hl,(VisitedPoints+4) ld de,(VisitedPoints+8) or a sbc hl,de jp p,+ dec hl ld a,h \ cpl \ ld h,a ld a,l \ cpl \ ld l,a + call ScaleX.HL ld (g_ellipseRX),hl ; Height = third position visited. ld hl,(VisitedPoints+2) ld bc,(VisitedPoints+10) or a sbc hl,bc jp p,+ dec hl ld a,h \ cpl \ ld h,a ld a,l \ cpl \ ld l,a + call ScaleY.HL ld (g_ellipseRY),hl call SetPatternBuffer ; Whew. call DrawEllipse pop iy ret ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotDrawSprite === ; ; Draws a sprite. Intended to be invoked by the BASIC PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- PlotDrawSprite ld a,(PlotShape) and %11 cp 2 jr nz,NotEorSprite call Sprite.DrawEor ret NotEorSprite ; This is slightly more interesting. ld a,(PlotMode) or a \ jr z,PlotSpritePlot dec a \ jr z,PlotSpriteOr dec a \ jr z,PlotSpriteAnd dec a \ jr z,PlotSpriteEor jp Sprite.DrawEor PlotSpriteEor ld a,(CurrentColour) and %01000000 ret z jp Sprite.DrawEor PlotSpriteAnd ld a,(CurrentColour) and %01000000 ret nz jp Sprite.DrawAnd PlotSpriteOr ld a,(CurrentColour) and %01000000 ret z jp Sprite.DrawOr PlotSpritePlot ld a,(CurrentColour) and %01000000 jp nz,Sprite.DrawOr ld hl,(Sprite.SpriteData) ld de,OP1 ld (Sprite.SpriteData),de ld b,8 - ld a,(hl) cpl ld (de),a inc hl inc de djnz - jp Sprite.DrawAnd ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.FloodFillNotBack === ; ; Flood-fills to a non-background colour. Intended to be invoked by the BASIC ; PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- FloodFillNotBack ld c,1 jr + ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.FloodFillFore === ; ; Flood-fills to the foreground colour. Intended to be invoked by the BASIC ; PLOT command. ; ;@doc:end ;------------------------------------------------------------------------------- FloodFillFore ld c,2 + call GetCurrentCoordinate ret c ; So, (ixh, ixl) are clipped to somewhere sensible. ; We now need to work out if we can fill. ; Fill to non-background colours: Current pixel must be <> background colour. ; Fill to foreground: Current pixel must be = foreground colour. ld a,ixh ld l,b ; ixl call GetPixelInfo ld b,a and (hl) push iy ld iyl,a ld a,(ForegroundColour) dec c jr nz,+ ld a,(BackgroundColour) cpl + add a,a add a,a sbc a,a ; a = $00 or a = $FF xor (hl) and b jr nz,+ pop iy ret + call Graphics.FloodFill.AllocMem jr nc,+ pop iy ; No room ld hl,Errors.NoRoom .bjump _Host.ReportError + call SetPatternBuffer ld a,(PlotMode) or a jr z,CanFloodFill dec a jr nz,+ ; OR filling ld a,iyl or a jr z,CanFloodFill pop iy ret + dec a jr nz,+ ; AND filling. ld a,iyl or a jr nz,CanFloodFill pop iy ret + dec a jr nz,+ ; EOR filling. ld a,iyl or a jr z,CanFloodFill ld hl,PatternBuffer ld b,8 - ld a,(hl) cpl ld (hl),a inc hl djnz - jr CanFloodFill + dec a jr z,+ pop iy ret + ; Invert filling. ld a,iyl or a ld a,127 jr z,+ xor a + ld (CurrentColour),a call SetPatternBuffer CanFloodFill .fcall "Graphics.FloodFill.FillToColour" ld a,(Vdu.WriteToLCDEnabled) or a pop iy ret z jp Copy ;------------------------------------------------------------------------------- ;@doc:routine ; ; === Graphics.PlotIsInverted === ; ; Establishes whether the current plot mode is an inverting one or not. ; ; INPUTS: ; MEMORY ; * Graphics.PlotMode - The current plot mode. ; * Graphics.PlotShape - The current shape being plotted. ; ; OUTPUTS: ; REGISTERS ; * F - Z set if the current plotting mode or shape is an inverting one. ; ; DESTROYED: ; REGISTERS ; * AF ; ;@doc:end ;------------------------------------------------------------------------------- PlotIsInverted ld a,(PlotMode) cp 4 ret z ld a,(PlotShape) and %11 cp 2 ret