[SOLVED] PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

[SOLVED] PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by Mijikai »

Linux Debian 12 (has #PB_PixelFormat_ReversedY)

Image:
Image

1 - The square on screen (see Image) should be only gray but there is an artifact with different color!
2 - If the square goes out the top right corner the program will crash!

Can someone confirm ?

Code:

Code: Select all

EnableExplicit

Procedure.i main()
  Protected.i exit,x,y,px,py,sx,sy,ex,ey,bytes
  Protected.long *s,*d,*w,*h
  If InitSprite() And InitKeyboard()
    If OpenWindow(0,0,0,800,600,"Test",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
      If OpenWindowedScreen(WindowID(0),0,0,WindowWidth(0),WindowHeight(0))
        SetFrameRate(60)
        x = WindowWidth(0) >> 1
        y = WindowHeight(0) >> 1
        Repeat
          Repeat
            Select WindowEvent()
              Case #PB_Event_None
                Break
              Case #PB_Event_CloseWindow
                exit = #True
            EndSelect
          ForEver
          ExamineKeyboard()
          If KeyboardPushed(#PB_Key_Left)
            x - 2  
          EndIf
          If KeyboardPushed(#PB_Key_Right)
            x + 2  
          EndIf
          If KeyboardPushed(#PB_Key_Up)
            y - 2
          EndIf
          If KeyboardPushed(#PB_Key_Down)
            y + 2
          EndIf
          ClearScreen(0)
          StartDrawing(ScreenOutput())
          DrawingMode(#PB_2DDrawing_AllChannels)
          *w = ?red_square
          *h = ?red_square + 4
          *s = ?red_square + 8
          *d = DrawingBuffer()
          sx = x - *w\l >> 1
          sy = y - *h\l >> 1
          ex = sx + *w\l - 1
          ey = sy + *h\l - 1
          If ex - sx <> 9
            Debug "THIS SHOULD NEVER SHOW!"
          EndIf
          If ey - sy <> 7
            Debug "THIS SHOULD NEVER SHOW!"
          EndIf
          bytes = DrawingBuffer() + (OutputHeight() * DrawingBufferPitch()) - (OutputDepth() >> 3)
          For py = sy To ey
            For px = sx To ex
              If px >= 0 And px < WindowWidth(0) And py >= 0 And py < WindowHeight(0)
                Debug Str(px) + " x " + Str(py);<- this will never exceed the screen coordinates!
                *d = DrawingBuffer() + (py * DrawingBufferPitch()) + (px * (OutputDepth() >> 3))
                *d\l = *s\l
              EndIf
              If *s\l <> $FF444444
                Debug "THIS WILL NEVER SHOW BECAUSE WE DONT DRAW A WRONG COLOR!"
              EndIf
              If *d > bytes
                Debug "THIS WILL NEVER SHOW BECAUSE WE DRAW INSIDE THE SCREEN ONLY!"
              EndIf
              *s + 4
            Next
          Next
          StopDrawing()
          FlipBuffers()
        Until exit = #True Or KeyboardReleased(#PB_Key_Escape)
        CloseScreen()
      EndIf
      CloseWindow(0)  
    EndIf
  EndIf
  ProcedureReturn #Null
EndProcedure

End main()

DataSection
  red_square:
  Data.l 10,8
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
EndDataSection
Last edited by Mijikai on Sat Jun 14, 2025 6:29 pm, edited 1 time in total.
User avatar
moulder61
Enthusiast
Enthusiast
Posts: 193
Joined: Sun Sep 19, 2021 6:16 pm
Location: U.K.

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by moulder61 »

@Mijikai

I can confirm on Void Linux using PB621 (Ubuntu 2024 x64 version) it does exactly what you say. The square has to be slightly off the top of the screen for it to crash. It seems OK on all the other corners.

Disclaimer: Some observations as a non expert.

Regarding the colour of the square, your data section says it's a red square but obviously it's grey, as you say, yet the artifact is actually red. Coincidence?

I'm guessing from the data statements that it's supposed to be a 10x8 "square", but on taking a screenshot and zooming in, it's actually 11x8. I don't really understand your code enough to know how it gets the sprite/square from the data, it looks well complicated to me!

Moulder.
"If it ain't broke, fix it until it is!

This message is brought to you thanks to SenselessComments.com

My PB stuff for Linux: "https://u.pcloud.link/publink/show?code ... z3MR0T3jyV
User avatar
moulder61
Enthusiast
Enthusiast
Posts: 193
Joined: Sun Sep 19, 2021 6:16 pm
Location: U.K.

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by moulder61 »

@Mijikai

I just spent a long time chatting to my new friend chatGPT. :shock:

Long story short, it fixed the issues with crashing and the red strip.

I have to say, it made a lot of s*** up along the way, even admitting to me that it did exactly that, made stuff up!

Ultimately, it came up with a solution though, so if you want me to post it I will, but largely it was to do with bit depth if you'd rather try to work it out for yourself?

Moulder.
"If it ain't broke, fix it until it is!

This message is brought to you thanks to SenselessComments.com

My PB stuff for Linux: "https://u.pcloud.link/publink/show?code ... z3MR0T3jyV
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by Mijikai »

@moulder61 thank you for testing.

The red_square is because i wrote this code originally as an example for another thread.
But since the red artefact is hard to see i changed the color to gray in this example.
Your observation is corrent it will draw a 11 x 8 instead of the 10 x 8 square (1 pixel artfact pixel on each line).

About the sprite square:

Code: Select all

EnableExplicit

Procedure.i main()
  
  Protected.l screen_width,screen_height
  Protected.l sprite_width,sprite_height
  Protected.l mouse_x,mouse_y
  Protected.l x,y,w,h;<- sprite output rect
  Protected.l i
  
  screen_width  = 800
  screen_height = 600
  
  sprite_width  = 10
  sprite_height = 8
  
  ;lets assume the mouse is in the
  ;middle of the screen:
  
  mouse_x = screen_width  / 2 
  mouse_y = screen_height / 2
  
  ;lets draw the sprite 
  ;centered on the mouse position
  ;calculate the srpite position:
  
  x = mouse_x - (sprite_width  / 2)
  y = mouse_y - (sprite_height / 2)
 
  w = x + sprite_width  - 1
  h = y + sprite_height - 1
  
  Debug "sprite start position:"
  Debug "x = " + Str(x)
  Debug "y = " + Str(y)
  Debug "sprite end position:"
  Debug "w = " + Str(w)
  Debug "h = " + Str(h)
  Debug "sprite size (to iterate):"
  Debug "width  = " + Str(w - x);<- just to verify!
  Debug "height = " + Str(h - y)
  
  ;now its possible to iterate from x to w & y to h
  ;and draw in the pixels but first check
  ;if it is within the drawing area
  ;in my example i use a slow per pixel test
  
  ;just to verify all pixels are within the valid range:
  
  Debug "range test for x:"
  For i = x To w
    Debug i - x
  Next
  
  Debug "range test for y:"
  For i = y To h
    Debug i - y
  Next
  
  ProcedureReturn #Null
EndProcedure

End main()
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by Mijikai »

moulder61 wrote: Sat Jun 14, 2025 5:32 pm I just spent a long time chatting to my new friend chatGPT. :shock:
The example takes into account the bit depth and
calculates the address of the destination pixel like this:

Code: Select all

DrawingBuffer() + (Y * DrawinBufferPitch()) + (X * (OutputDepth() >> 3))
Edit:
Also the drawing range is limited so there is no way ( that i see)
for an additional pixel to magically appear !

I dont see my mistake, so please post the solution.
User avatar
kenmo
Addict
Addict
Posts: 2043
Joined: Tue Dec 23, 2003 3:54 am

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by kenmo »

Check your bit depth... I'm assuming it's 24-bit (3 bytes) but you're poking 32-bit longs, so the alpha byte (FF) of the last pixel in each row is spilling into the red channel of the next pixel...
User avatar
Mijikai
Addict
Addict
Posts: 1520
Joined: Sun Sep 11, 2016 2:17 pm

Re: PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by Mijikai »

kenmo wrote: Sat Jun 14, 2025 6:22 pm ...(3 bytes) but you're poking 32-bit longs, so the alpha byte (FF) of the last pixel in each row is spilling into the red channel of the next pixel...
Thank you @kenmo
That makes sense, thanks :)
Case closed!
User avatar
moulder61
Enthusiast
Enthusiast
Posts: 193
Joined: Sun Sep 19, 2021 6:16 pm
Location: U.K.

Re: [SOLVED] PB 6.21 (x64) possible 2DDrawing Bugs on Linux!?

Post by moulder61 »

@Mijikai

kenmo was right, basically.

I just told chatGPT what was going wrong then pasted your code in and asked it to fix it. This was after asking it to explain a few things to me so I could understand it a bit better. As I said before, it took a while. It kept using non PB commands, not putting relevant commands inside the StartDrawing() function, using backslashes for a division operator, then insisted on it when I explained that backslash was used for structures(I was making stuff up then), telling me the code was tested and when I asked how it was testing it, it said it was using PB 6.51 for Windows?! I called bullshit and it apologised. :lol:

I ended up telling it humanity wasn't in danger from AI just yet. :P

Anyway, here's the modification of your code that chatGPT came up with, eventually:

Moulder.

Code: Select all

EnableExplicit

Procedure.i main()
  Protected exit = #False
  Protected x.i, y.i, px.i, py.i, sx.i, sy.i
  Protected width.i, height.i, pitch.i, bpp.i
  Protected *src, *dst
  Protected pixelValue.l
  Protected screenWidth.i = 0, screenHeight.i = 0

  If InitSprite() And InitKeyboard()
    If OpenWindow(0, 0, 0, 800, 600, "PureBasic Linux Grey Box", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
      If OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))
        screenWidth = WindowWidth(0)
        screenHeight = WindowHeight(0)

        SetFrameRate(60)
        x = screenWidth / 2
        y = screenHeight / 2

        Repeat
          Repeat
            Select WindowEvent()
              Case #PB_Event_None
                Break
              Case #PB_Event_CloseWindow
                exit = #True
            EndSelect
          ForEver

          ExamineKeyboard()
          If KeyboardPushed(#PB_Key_Left)  : x = x - 2 : EndIf
          If KeyboardPushed(#PB_Key_Right) : x = x + 2 : EndIf
          If KeyboardPushed(#PB_Key_Up)    : y = y - 2 : EndIf
          If KeyboardPushed(#PB_Key_Down)  : y = y + 2 : EndIf

          ClearScreen(0)

          StartDrawing(ScreenOutput())
            DrawingMode(#PB_2DDrawing_AllChannels)

            pitch = DrawingBufferPitch()
            bpp = OutputDepth() / 8
            *src = ?red_square + 8  ; pixel data start

            width = PeekL(?red_square)
            height = PeekL(?red_square + 4)

            sx = x - width / 2
            sy = y - height / 2

            ; Draw row by row with clipping and correct pixel format
            For py = 0 To height - 1
              Protected destY = sy + py
              If destY < 0 Or destY >= screenHeight
                *src + width * 4  ; skip this row in source
                Continue
              EndIf

              For px = 0 To width - 1
                Protected destX = sx + px
                If destX >= 0 And destX < screenWidth
                  *dst = DrawingBuffer() + (destY * pitch) + (destX * bpp)

                  ; Read pixel from source (always 32-bit ARGB in data)
                  pixelValue = PeekL(*src)

                  ; Convert pixelValue if output depth is 24-bit (RGB)
                  If bpp = 3
                    ; Extract ARGB components
                    Protected alpha = (pixelValue >> 24) & $FF
                    Protected red   = (pixelValue >> 16) & $FF
                    Protected green = (pixelValue >> 8) & $FF
                    Protected blue  = pixelValue & $FF
                    ; Compose 24-bit RGB (no alpha)
                    pixelValue = (red) | (green << 8) | (blue << 16)
                    ; Write 3 bytes manually
                    PokeB(*dst, blue)
                    PokeB(*dst + 1, green)
                    PokeB(*dst + 2, red)
                  ElseIf bpp = 4
                    ; For 32-bit, Linux usually uses RGBA or BGRA; assume BGRA, so reorder:
                    ; Original data is ARGB ($FF444444) which is A=FF, R=44, G=44, B=44
                    ; Rearrange ARGB to BGRA for Linux
                    Protected a = (pixelValue >> 24) & $FF
                    Protected r = (pixelValue >> 16) & $FF
                    Protected g = (pixelValue >> 8) & $FF
                    Protected b = pixelValue & $FF
                    ; Compose BGRA
                    pixelValue = (b) | (g << 8) | (r << 16) | (a << 24)
                    PokeL(*dst, pixelValue)
                  EndIf
                EndIf
                *src + 4
              Next
            Next

          StopDrawing()
          FlipBuffers()

        Until exit Or KeyboardReleased(#PB_Key_Escape)

        CloseScreen()
      EndIf
      CloseWindow(0)
    EndIf
  EndIf

  ProcedureReturn #Null
EndProcedure

End main()

DataSection
  red_square:
  Data.l 10, 8
  ; ARGB format: Alpha=FF, Red=44, Green=44, Blue=44 - grey
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
  Data.l $FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444,$FF444444
EndDataSection
"If it ain't broke, fix it until it is!

This message is brought to you thanks to SenselessComments.com

My PB stuff for Linux: "https://u.pcloud.link/publink/show?code ... z3MR0T3jyV
Post Reply