Basic Univers
sprite$ = #PB_Compiler_Home + "Examples\Sources\Data\Geebee2.bmp"


If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf
If InitSprite3D() = 0
  MessageRequester("Error", "Direct3D system can't be initialized correctly", 0)
  End
EndIf

Procedure SpriteMirrorHorizontal(SpriteID)
  ; Mirrors a sprite horizontal
  StartDrawing(SpriteOutput(SpriteID))
  IW = SpriteWidth(SpriteID)
  IH = SpriteHeight(SpriteID)
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
  
  *pxData1.Long = Buffer
  *pxData2.Long = *pxData1 +(IH - 1)*Pitch
  
  mem = AllocateMemory(Pitch)
  For lines = 0 To IH/2 - 1
    CopyMemory(*pxData1, mem, Pitch)
    CopyMemory(*pxData2, *pxData1, Pitch)
    CopyMemory(mem, *pxData2, Pitch)
    *pxData1 + Pitch
    *pxData2 - Pitch
  Next
  StopDrawing()
  If mem: FreeMemory(mem): EndIf
  
EndProcedure


Procedure SpriteMirrorVertical(SpriteID)
  ; Mirrors a sprite vertical
  StartDrawing(SpriteOutput(SpriteID))
  IW = SpriteWidth(SpriteID)
  IH = SpriteHeight(SpriteID)
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
  
  *pxData1.Long = Buffer
  *pxData2.Long = *pxData1 +(IH - 1)*Pitch
  PixelFormat = DrawingBufferPixelFormat()
  ByteOffset = 4
  Select PixelFormat
    Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
      ByteOffset = 1
    Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
      ByteOffset = 3
    Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
      ByteOffset = 3
    Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
      ByteOffset = 4
    Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
      ByteOffset = 4
  EndSelect
  
  For lines = 0 To IH - 1
    *pxData1 = Buffer +(lines*Pitch)
    *pxData2 = *pxData1 + Pitch - 4
    For t = 0 To(IW/2)- 1
      m =*pxData1\l
      *pxData1\l =*pxData2\l
      *pxData2\l = m
      *pxData1 + ByteOffset
      *pxData2 - ByteOffset
    Next
  Next
  StopDrawing()
  
EndProcedure


Procedure SpriteGray(id)
  ; grays a ID
  If IsSprite(id)= 0: ProcedureReturn 0: EndIf
  
  StartDrawing(SpriteOutput(id))
  IW = SpriteWidth(id)
  IH = SpriteHeight(id)
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
  *pxData1.Long
  PixelFormat = DrawingBufferPixelFormat()
  
  Select PixelFormat
    Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
      ByteOffset = 1
    Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
      ByteOffset = 3
    Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
      ByteOffset = 3
    Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
      ByteOffset = 4
    Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
      ByteOffset = 4
  EndSelect
  
  For lines = 0 To IH - 1
    *pxData1 = Buffer +(lines*Pitch)
    For t = 0 To IW - 1
      m =*pxData1\l
      
      Select PixelFormat
        Case #PB_PixelFormat_16Bits
          
        Case #PB_PixelFormat_24Bits_BGR, #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
          
          p = m >> 24 & $FF ; the additive alpha
          r = m >> 16 & $FF
          g = m >> 8 & $FF
          b = m  & $FF
          gray =((r*29)+(g*58)+(b*11))/100
          m =   gray | gray << 8 | gray << 16 | p << 24
          
        Case #PB_PixelFormat_24Bits_RGB, #PB_PixelFormat_32Bits_RGB
          p = m >> 24 & $FF ; the additive alpha
          b = m >> 16 & $FF
          g = m >> 8 & $FF
          r = m  & $FF
          gray =((r*29)+(g*58)+(b*11))/100
          m =   gray | gray << 8 | gray << 16 | p << 24
          
      EndSelect
      
      *pxData1\l = m
      *pxData1 + ByteOffset
    Next
  Next
  StopDrawing()
  
EndProcedure

Procedure SpriteShadow(id, TransparentColor = 0)
  ; transform a sprite into a shadow
  If IsSprite(id)= 0: ProcedureReturn 0: EndIf
  
  StartDrawing(SpriteOutput(id))
  IW = SpriteWidth(id)
  IH = SpriteHeight(id)
  Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
  Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
  *pxData1.Long
  PixelFormat = DrawingBufferPixelFormat()
  
  Select PixelFormat
    Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
      ByteOffset = 1
    Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
      ByteOffset = 2
    Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
      ByteOffset = 3
    Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
      ByteOffset = 3
    Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
      ByteOffset = 4
    Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
      ByteOffset = 4
  EndSelect
  
  For lines = 0 To IH - 1
    *pxData1 = Buffer +(lines*Pitch)
    For t = 0 To IW - 1
      m =*pxData1\l
      If m = TransparentColor
        ; do nothing
      Else
        m = 0
      EndIf
      *pxData1\l = m
      *pxData1 + ByteOffset
    Next
  Next
  StopDrawing()
  
EndProcedure


If OpenScreen(800, 600, 32, "Sprite")
  
  lp = LoadSprite(0, sprite$, #PB_Sprite_Texture)
  If lp = 0
    Debug "sprite not loaded"
    End
  EndIf
  TransparentSpriteColor(0, RGB(255, 0, 255)) ; Our pink is transparent :)
  
  ; Draw some boxes
  StartDrawing(SpriteOutput(0))
  Box(0, 0, 30, 30, RGB(250, 250, 50))
  Box(SpriteWidth(0)- 30, 0, 30, 30, RGB(50, 250, 50))
  Box(SpriteWidth(0)- 30, SpriteHeight(0)- 30, 30, 30, RGB(50, 50, 250))
  Box(0, SpriteHeight(0)- 30, 30, 30, RGB(50, 250, 250))
  StopDrawing()
  
  CopySprite(0, 1,  #PB_Sprite_Texture)
  SpriteMirrorHorizontal(1)
  TransparentSpriteColor(1, RGB(255, 0, 255)) ; Our pink is transparent :)
  CopySprite(0, 2,  #PB_Sprite_Texture)
  SpriteMirrorVertical(2)
  TransparentSpriteColor(2, RGB(255, 0, 255)) ; Our pink is transparent :)
  
  CopySprite(0, 3,  #PB_Sprite_Texture)
  SpriteGray(3)
  TransparentSpriteColor(3, RGB(255, 0, 255)) ; Our pink is transparent :)
  
  CopySprite(0, 4,  #PB_Sprite_Texture)
  SpriteShadow(4, RGB(255, 0, 255))
  TransparentSpriteColor(4, RGB(255, 0, 255)) ; Our pink is transparent :)
  
  Repeat
    FlipBuffers()
    ClearScreen(RGB(200, 200, 255))
    DisplaySprite(0, 00, 30) ; original
    DisplayTransparentSprite(1, 200, 30) ; horizontal
    DisplayTransparentSprite(2, 400, 30) ; vertical
    DisplayTransparentSprite(3, 600, 30) ; gray
    
    DisplayTransparentSprite(4, 0, 230) ; Shadow
    
    ExamineKeyboard()
    x + 1
  Until x > 2500 Or KeyboardPushed(#PB_Key_Escape)
Else
  MessageRequester("Error", "Can't open a screen !", 0)
EndIf
End