The following code is a Method within a custom `bitmap` type, which draws a line of pixels at any angle, pixel by pixel. The code has been cropped t show only one of the drawing modes (replace mode). Clipping is optionally performed. In the program I am testing with, I call the method as follows:
Test1.PixelLine(-50,-50,x*4,y*4,$FFFFFFFF,0,False)
I can apparently set clipping to True or False and I get the same problem.
The problem is, when I compile my test program with Debug On, the program works correctly and the lines are drawn. When I compile with Debug Off, the program only draws the first pixel of the line. (Normally you'd think it'd be the other way around, or that the debugging wouldn't change behavior?!)
So far I can only tell that, with Debug Off, the program flow doesn't seem to get into the `While` loops, failing the test right away.
Does anyone see what might be causing this strange problem? How can I get this to run with debug off?
(P.S. use the code for whatever you like, it's not the best but it works - usually.)
The Type fields are as follows if you need to know:
Test1.PixelLine(-50,-50,x*4,y*4,$FFFFFFFF,0,False)
I can apparently set clipping to True or False and I get the same problem.
The problem is, when I compile my test program with Debug On, the program works correctly and the lines are drawn. When I compile with Debug Off, the program only draws the first pixel of the line. (Normally you'd think it'd be the other way around, or that the debugging wouldn't change behavior?!)
So far I can only tell that, with Debug Off, the program flow doesn't seem to get into the `While` loops, failing the test right away.
Does anyone see what might be causing this strange problem? How can I get this to run with debug off?
Method PixelLine(MXpos1:Int,MYpos1:Int,MXpos2:Int,MYPos2:Int,MColor:Int=$FFFFFFFF,MMode:Int=0,MClip:Int=False) 'To draw a diagonal/straight line of pixels on this `Bitmap` from MXpos,MYpos to MXpos2,MYpos2 'in the given `color` MColor (RGBA) or with XXYY value for each pixel 'Uses the Bresenham's line drawing algorithm with integer math only 'Requires that at least one pixel must be drawable and is within the this `Bitmap` object's memory space if clipping is off 'Performs clipping if MClip is True 'Copies differently based on the MMode. 0=Replace Local MRowBytes:Int=Width 'RowBytes/4 because it's an Int Pointer Local MBasePointer:Int Ptr=DataBankIntPtr 'Base address of bitmap memory Local MColorFast:Int=MColor 'Make sure it's in a register for speed Local MSteep:Int=Abs(MYpos2-MYpos1) > Abs(MXpos2-MXpos1) 'Boolean If MSteep '=True? Local MTemp:Int=MXpos1; MXpos1=MYpos1; MYpos1=MTemp 'Swap X1,Y1 MTemp=MXpos2; MXpos2=MYpos2; MYpos2=MTemp 'Swap X2,Y2 EndIf Local MDeltaX:Int=Abs(MXpos2-MXpos1) 'X Difference Local MDeltaY:Int=Abs(MYpos2-MYpos1) 'Y Difference Local MError:Int=0 'Overflow counter Local MDeltaError:Int=MDeltaY 'Counter adder Local MX:Int=MXpos1 'Start at X1,Y1 Local MY:Int=MYpos1 Local MXStep:Int Local MYStep:Int If MXpos1<MXpos2 Then MXStep=1 Else MXStep=-1 'Direction If MYpos1<MYpos2 Then MYStep=1 Else MYStep=-1 'Direction Select MMode 'Redirect flow Case 1 If (MColorFast & $000000FF) Then MMode=0 Case 2 If (MaskValue<>MColorFast) Then MMode=0 Case 5 If (MaskValue=MColorFast) Then MMode=0 Case 9 If (MColorFast & $000000FF) Then MMode=0 End Select Local MClipFast:Int=MClip 'For speed Local MWidthFast:Int=Width 'For speed Local MHeightFast:Int=Height 'For speed Local MClipping:Int=False 'For signalling that a line started outside of the bitmap Select MMode Case 0 'Replace mode - Copies RGBA/XXYY solidly overwriting all data If MSteep If MClipFast If MY>-1 And MY<MWidthFast And MX>-1 And MX<MHeightFast (MBasePointer+MY+(MX*MRowBytes))[0]=MColorFast 'Replace at Y,X MClipping=False 'Does the line start outside the bitmap? Else MClipping=True 'The line starts outside the bitmap EndIf Else (MBasePointer+MY+(MX*MRowBytes))[0]=MColorFast 'Replace at Y,X EndIf Else If MClipFast If MX>-1 And MX<MWidthFast And MY>-1 And MY<MHeightFast (MBasePointer+MX+(MY*MRowBytes))[0]=MColorFast 'Replace at X,Y MClipping=False 'Does the line start outside the bitmap? Else MClipping=True 'The line starts outside the bitmap EndIf Else (MBasePointer+MX+(MY*MRowBytes))[0]=MColorFast 'Replace at X,Y EndIf EndIf If MClipFast While MX<>MXpos2 MX:+MXStep 'Move in X MError:+MDeltaError 'Add to counter If (MError Shl 1)>MDeltaX 'Would it overflow? MY:+MYStep 'Move in Y MError=MError-MDeltaX 'Overflow/wrap the counter EndIf If MClipping=False 'Inside the bitmap, draw the pixel If MSteep If (MY<0) Or (MY>=MWidthFast) Or (MX<0) Or (MX>=MHeightFast) Then Return (MBasePointer+MY+(MX*MRowBytes))[0]=MColorFast 'Replace at Y,X Else If (MX<0) Or (MX>=MWidthFast) Or (MY<0) Or (MY>=MHeightFast) Then Return (MBasePointer+MX+(MY*MRowBytes))[0]=MColorFast 'Replace at X,Y EndIf Else 'Outside the bitmap, check if it came inside If MSteep If (MY>-1) And (MY<MWidthFast) And (MX>-1) And (MX<MHeightFast) Then MClipping=False Else If (MX>-1) And (MX<MWidthFast) And (MY>-1) And (MY<MHeightFast) Then MClipping=False EndIf EndIf Wend Else While MX<>MXpos2 MX:+MXStep 'Move in X MError:+MDeltaError 'Add to counter If (MError Shl 1)>MDeltaX 'Would it overflow? MY:+MYStep 'Move in Y MError=MError-MDeltaX 'Overflow/wrap the counter EndIf If MSteep (MBasePointer+MY+(MX*MRowBytes))[0]=MColorFast 'Replace at Y,X Else (MBasePointer+MX+(MY*MRowBytes))[0]=MColorFast 'Replace at X,Y EndIf Wend EndIf End Select End Method
(P.S. use the code for whatever you like, it's not the best but it works - usually.)
The Type fields are as follows if you need to know:
Field DataBankPtr:Byte Ptr 'Byte-Pointer to the actual memory reserved in the bank Field DataBankIntPtr:Int Ptr 'Int-Pointer to the memory in the bank Field DataBank:TBank 'Pointer to a TBank object to store data Field Width:Int 'Total width of the bitmap in terms of pixels or units of representation Field Height:Int 'Total height of the bitmap in terms of pixels or units of representation Field RowBytes:Int 'How many total bytes of data are allocated in each row of pixels or units (Width*4) Field TotalBytes:Int 'How many bytes in total does the bitmap data take up Field FromPixmap:TPixmap 'Pointer to a Pixmap object which may have been used for loading data from an image, used as a static bank Field MaskValue:Int 'RGBA color or 4-byte value, where all pixels in the Bitmap of that color/value are transparent/non-copied when copying in Mode 2 (ValueMask mode)