Structure Help Please

Just starting out? Need help? Post your questions and find answers here.
Hysteria
User
User
Posts: 50
Joined: Sat Oct 23, 2010 8:51 am
Location: UK

Structure Help Please

Post by Hysteria »

Being a 'structure novice' when I look at the PB example below, it looks like the author is doing something 'clever' with the structure facility which I can't quite fathom. My non-oop brain fails to get the benefit of things like structures (it thinks, perhaps wrongly, they are doing things the long way when there is a more concise way) so struggles with their use.

However, this code seems to be using one to create a new Type called Pixel which confusingly (to me) defines a long variable called Pixel! So I presume each Pixel will be 32bits in size; fair enough.

I guess what really confuses me is

Code: Select all

*Line\Pixel = ColorTable(pos2) ; Write the pixel directly to the memory !
*Line+4
I understand *line is a pointer to a location in video memory and *Line+4 increments the pointer by 4 bytes
but my brain is failing me with *Line\Pixel. I know an instance of 'line' has been created (and it gets 'created' multiple times it seems - maybe that doesn't matter as it's a pointer) by *Line.Pixel = Buffer+Pitch*y. And it looks like by assigning a value to the pointer in this configuration we are writing the value of ColorTable(pos2) to memory. But as I say, I can't quite see how it works.

If anyone could help clarify this I'd be very grateful. Also, If anyone has the time to show me how the same thing could be done without the use of the Structure (by using Poke) that would help me too.

Finally, for any Mac users - you (we) get the results of this demo in grey not blue. Once I can see what data is being put where I'll try to figure out why.

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - Drawing via Direct Screen Access (DSA) 
;
;    (c) 2006 - Fantaisie Software
;
; ------------------------------------------------------------
;
; Note: disable the debugger to run at full speed !
;


#ScreenWidth  = 800  ; Feel free to change this to see the pixel filling speed !
#ScreenHeight = 600

If InitSprite() = 0 Or InitKeyboard()=0
  MessageRequester("Error","DirectX 7+ is needed.",0)
EndIf

Structure Pixel
  Pixel.l
EndStructure

Procedure.f GSin(angle.f)
  ProcedureReturn Sin(angle*(2*3.14/360))
EndProcedure

; Pre-calculated values are faster than realtime calculated ones...
; ... so we save them in an array before starting gfx operations
Dim CosTable(#ScreenWidth*2)
Dim ColorTable(255)

For i = 0 To #ScreenWidth*2
  CosTable(i) = GSin(360*i/320)* 32 + 32
Next


If OpenScreen(#ScreenWidth, #ScreenHeight, 32, "PB Plasma")

  Repeat

    Wave+6
    If Wave > 320 : Wave = 0 : EndIf
    
    If StartDrawing(ScreenOutput())
      Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
      Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
      PixelFormat = DrawingBufferPixelFormat()  ; Get the pixel format. 
      
      If PixelFormat = #PB_PixelFormat_32Bits_RGB
        For i = 0 To 255
          ColorTable(i) = i << 16 ; Blue is at the 3th pixel
        Next
      Else                        ; Else it's 32bits_BGR
        For i = 0 To 255
          ColorTable(i) = i       ; Blue is at the 1th pixel
        Next    
      EndIf
    
      For y = 0 To #ScreenHeight-1
        pos1 = CosTable(y+wave)
        
        *Line.Pixel = Buffer+Pitch*y
        
        For x = 0 To #ScreenWidth-1
          pos2 = (CosTable(x+Wave) + CosTable(x+y) + pos1)
          *Line\Pixel = ColorTable(pos2) ; Write the pixel directly to the memory !
          *Line+4
        Next
      Next
      
      StopDrawing()
    EndIf
    
    ExamineKeyboard()
    
    FlipBuffers()
     
  Until KeyboardPushed(#PB_Key_Escape)

Else
  MessageRequester("Error","Can't open the screen !",0)
EndIf

End
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: Structure Help Please

Post by Comtois »

the poke version, just change these lines

Code: Select all

 *Line = Buffer+Pitch*y
       
        For x = 0 To #ScreenWidth-1
          pos2 = (CosTable(x+Wave) + CosTable(x+y) + pos1)
          PokeL(*Line, ColorTable(pos2)) ; Write the pixel directly to the memory !
          *Line+4
        Next
Please correct my english
http://purebasic.developpez.com/
User avatar
idle
Always Here
Always Here
Posts: 5916
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Structure Help Please

Post by idle »

maybe this may make it clearer, though I'm not the best at explaining things!

The example shows the use of a structured pointer, which enables you to reference the memory that the pointer is pointing to
with the syntax of a structure. In this case an integer called ThePixelsValue.

Code: Select all


Structure Pixel
  ThePixelValue.l
EndStructure

;define a structured pointer of the type Pixel  
protected *line.Pixel 

*line = Buffer+Pitch*y;  ;set pointer *line to point to the video memory buffer at the start of line y 

;set the memory at Buffer+Pitch*y 
*line\ThePixelValue = ColorTable(pos2) 

;get the memory at Buffer+Pitch*y
x = *line\ThePixelValue

;increment the pointer by the required size of what your looking at.
*line + 4 

Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Structure Help Please

Post by netmaestro »

The concept of a structured pointer is actually the simplest and most concise of all your options for writing to memory. Not to mention it's nearly self-documenting as well. Take the following structure:

Code: Select all

Structure BGRA
  Blue.l
  Green.l
  Red.l
  Alpha.l
EndStructure
If you want to use a simple pointer and PokeL() for writing to memory, you would have to do:

Code: Select all

*ptr = memorylocation
PokeL(*ptr,<bluevalue>)
*ptr+SizeOf(LONG)
PokeL(*ptr, <greenvalue>)
*ptr+SizeOf(LONG)
PokeL(*ptr, <redvalue>)
*ptr+SizeOf(LONG)
PokeL(*ptr, <alphavalue>)
If you create a pointer of the BGRA type you can let Purebasic increment the write location automatically for you with:

Code: Select all

*ptr.BGRA = memorylocation
With *ptr
  \Blue = <bluevalue>
  \Green = <greenvalue>
  \Red = <redvalue>
  \Alpha = <alphavalue>
EndWith
BERESHEIT
Hysteria
User
User
Posts: 50
Joined: Sat Oct 23, 2010 8:51 am
Location: UK

Re: Structure Help Please

Post by Hysteria »

Many thanks guys, much appreciated. :D

Comtois - that was exactly what I needed, thanks! If only the original example had that.

Idle - thanks a lot for taking the time, that explanation was very helpful.

Netmaestro - I'm sure you're right in many cases, however, I'm not convinced that using a structure makes this particular example the simplest. Like many things, I suspect that some programmers gravitate towards this, perhaps, more modern approach and some, like me, prefer 'put this byte right there' approach :D
Post Reply