Page 1 of 1

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

Posted: Fri Jun 13, 2025 10:06 pm
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

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

Posted: Sat Jun 14, 2025 2:58 pm
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.

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

Posted: Sat Jun 14, 2025 5:32 pm
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.

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

Posted: Sat Jun 14, 2025 6:00 pm
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()

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

Posted: Sat Jun 14, 2025 6:11 pm
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.

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

Posted: Sat Jun 14, 2025 6:22 pm
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...

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

Posted: Sat Jun 14, 2025 6:29 pm
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!

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

Posted: Sat Jun 14, 2025 9:58 pm
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