December 04, 2020, 11:56:37 AM

Author Topic: [bb] PeekPoke Module for B3D/B+ by markcw [ 1+ years ago ]  (Read 624 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] PeekPoke Module for B3D/B+ by markcw [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : PeekPoke Module for B3D/B+
Author : markcw
Posted : 1+ years ago

Description : I was using BLTZMEM.dll by zjpierre until I read jfk's post about RtlMoveMemory and wrote this. The main advantages of using this module are no need for an extra dll and shorter function names.

Create a file in your userlibs folder called "peekpoke.decls"
Code: [Select]
.lib "Kernel32.dll"

;Win32 Decls, Memory Management Functions
Api_RtlMoveToBank(Destination*,Source,Length):"RtlMoveMemory"
Api_RtlMoveToMemory(Destination,Source*,Length):"RtlMoveMemory"
;Api_RtlFillMemory(Destination,Length,Fill):"RtlFillMemory"
;Api_RtlZeroMemory(Destination,Length):"RtlZeroMemory"

;PeekPoke Module Decls
PeekB%(address)
PeekS%(address)
PeekI%(address)
PeekF#(address)
PokeB(address,value)
PokeS(address,value)
PokeI(address,value)
PokeF(address,value#)
MemoryLog(address,ByteLength,filename$)

Save this code entry as "peekpoke.bb" and then include it in your main program. Examples are shown below. [/i]

Code :
Code: BlitzBasic
  1. ;PeekPoke Module for B3D/B+
  2. ;Author: markcw, edited 15 Mar 2008
  3. ;Allows direct memory access via Kernel32.dll
  4. ;Create a file in your userlibs folder called "peekpoke.decls"
  5.  
  6. ;.lib "Kernel32.dll"
  7. ;
  8. ;;Win32 Decls, Memory Management Functions
  9. ;Api_RtlMoveToBank(Destination*,Source,Length):"RtlMoveMemory"
  10. ;Api_RtlMoveToMemory(Destination,Source*,Length):"RtlMoveMemory"
  11. ;;Api_RtlFillMemory(Destination,Length,Fill):"RtlFillMemory"
  12. ;;Api_RtlZeroMemory(Destination,Length):"RtlZeroMemory"
  13. ;
  14. ;;PeekPoke Module Decls
  15. ;PeekB%(address)
  16. ;PeekS%(address)
  17. ;PeekI%(address)
  18. ;PeekF#(address)
  19. ;PokeB(address,value)
  20. ;PokeS(address,value)
  21. ;PokeI(address,value)
  22. ;PokeF(address,value#)
  23. ;MemoryLog(address,ByteLength,filename$)
  24.  
  25. ;This global has a long name to avoid a conflict
  26. Global Kernel32PeekPokeBank=CreateBank(4) ;Bank for memory access
  27.  
  28. Function PeekB(address) ;PeekByte
  29.  Api_RtlMoveToBank(Kernel32PeekPokeBank,address,1)
  30.  Return PeekByte(Kernel32PeekPokeBank,0)
  31. End Function
  32.  
  33. Function PeekS(address) ;PeekShort
  34.  Api_RtlMoveToBank(Kernel32PeekPokeBank,address,2)
  35.  Return PeekShort(Kernel32PeekPokeBank,0)
  36. End Function
  37.  
  38. Function PeekI(address) ;PeekInteger
  39.  Api_RtlMoveToBank(Kernel32PeekPokeBank,address,4)
  40.  Return PeekInt(Kernel32PeekPokeBank,0)
  41. End Function
  42.  
  43. Function PeekF#(address) ;PeekFloat
  44.  Api_RtlMoveToBank(Kernel32PeekPokeBank,address,4)
  45.  Return PeekFloat(Kernel32PeekPokeBank,0)
  46. End Function
  47.  
  48. Function PokeB(address,value) ;PokeByte
  49.  PokeByte Kernel32PeekPokeBank,0,value
  50.  Api_RtlMoveToMemory(address,Kernel32PeekPokeBank,1)
  51. End Function
  52.  
  53. Function PokeS(address,value) ;PokeShort
  54.  PokeShort Kernel32PeekPokeBank,0,value
  55.  Api_RtlMoveToMemory(address,Kernel32PeekPokeBank,2)
  56. End Function
  57.  
  58. Function PokeI(address,value) ;PokeInteger
  59.  PokeInt Kernel32PeekPokeBank,0,value
  60.  Api_RtlMoveToMemory(address,Kernel32PeekPokeBank,4)
  61. End Function
  62.  
  63. Function PokeF(address,value#) ;PokeFloat
  64.  PokeFloat Kernel32PeekPokeBank,0,value#
  65.  Api_RtlMoveToMemory(address,Kernel32PeekPokeBank,4)
  66. End Function
  67.  
  68. ;MemoryLog Functions
  69.  
  70. Function MemoryLog(address,ByteLength,filename$="memorylog.txt")
  71.  ;Writes a memory log text file, useful if you're searching for offsets
  72.  ;address -> where to start from, ByteLength -> length to copy
  73.  Local file,id,value,count,array$
  74.  file=WriteFile(filename$)
  75.  For id=0 To (ByteLength/4)-1 ;Write the line
  76.   MemoryLogValue(file,address) : WriteByte(file,43) ;Write "address+"
  77.   MemoryLogValue(file,id Shl 2) : WriteByte(file,32) ;Write "offset "
  78.   WriteByte(file,123) : WriteByte(file,32) ;Write "{ "
  79.   value=PeekI(address)
  80.   MemoryLogValue(file,value) : WriteByte(file,32) ;Write "Int "
  81.   WriteByte(file,58) : WriteByte(file,32) ;Write ": "
  82.   For count=0 To 3 Step 2 ;2 shorts
  83.    value=PeekS(address+count)
  84.    MemoryLogValue(file,value) ;Write "Short"
  85.    If count=0 Then WriteByte(file,44) ;Write ","
  86.    If count=2 Then WriteByte(file,32) ;Write " " if last
  87.   Next
  88.   WriteByte(file,58) : WriteByte(file,32) ;Write ": "
  89.   For count=0 To 3 ;4 bytes
  90.    value=PeekB(address+count)
  91.    MemoryLogValue(file,value) ;Write "Byte"
  92.    If count<3 Then WriteByte(file,44) ;Write ","
  93.    If count=3 Then WriteByte(file,32) ;Write " " if last
  94.   Next
  95.   WriteByte(file,58) : WriteByte(file,32) ;Write ": "
  96.   For count=0 To 3 ;4 chars
  97.    value=PeekB(address+count)
  98.    WriteByte(file,value) ;Write "Char"
  99.   Next
  100.   WriteByte(file,32) : WriteByte(file,58) ;Write " :"
  101.   array$=Str(PeekF(address))
  102.   WriteByte(file,32) : MemoryLogString(file,array$) ;Write " Float"
  103.   WriteByte(file,32) : WriteByte(file,125) ;Write " }"
  104.   WriteByte(file,13) : WriteByte(file,10) ;Write "EOL"
  105.   address=address+4 ;Get the next 4 bytes
  106.  Next
  107.  array$="Address  { Int : Short : Byte : Char : Float }"
  108.  MemoryLogString(file,array$) ;Write info string
  109.  WriteByte(file,13) : WriteByte(file,10) ;Write "EOL"
  110.  CloseFile file
  111. End Function
  112.  
  113. Function MemoryLogValue(file,value)
  114.  ;Writes an ascii byte, short or integer
  115.  Local stringarray$,id,char$
  116.  stringarray$=Str(value)
  117.  For id=1 To Len(stringarray$)
  118.   char$=Mid(stringarray$,id,1)
  119.   WriteByte(file,Asc(char$))
  120.  Next
  121. End Function
  122.  
  123. Function MemoryLogString(file,stringarray$)
  124.  ;Writes an ascii string
  125.  Local id,char$
  126.  For id=1 To Len(stringarray$)
  127.   char$=Mid(stringarray$,id,1)
  128.   WriteByte(file,Asc(char$))
  129.  Next
  130. End Function


Comments :


markcw(Posted 1+ years ago)

 This example is for b3d. It looks at the structure of an image in memory and then pokes the pixels with random colors.I have done a speed test with this method versus WritePixelFast and it is twice as slow. I assume this is because you need to pass the value to a bank and then to memory. I also tested passing to a bank per pixel and then passing the whole image in one go with RTL_MoveMemory and it still wasn't as fast as WritePixelFast although it was very close.
Code: [Select]
;PeekPoke Example, for Blitz3D

Include "peekpoke.bb" ;PeekPoke Module

Graphics 640,480,0,2
SetBuffer BackBuffer()

load=0 ;Flag to load or create an image
If load=1
 image=LoadImage("test.bmp")
Else
 width=100
 height=63
 frames=1
 image=CreateImage(width,height,frames)
EndIf

BufferList=PeekI(image+4) ;pImageBufferList
BufferListEnd=PeekI(image+8) ;pImageBufferListEnd
numframes=(BufferListEnd-BufferList)/4 ;Number of image frames

buffer=ImageBuffer(image,0)
pImageBuffer=PeekI(BufferList+(0*4)) ;pImageBuffer[frame]

LockBuffer buffer ;LockBuffer to return a pointer to the pixels
UnlockBuffer buffer
DDSurface7=PeekI(buffer+12) ;pImageDDSurface7
PixelData=PeekI(buffer+72) ;pImagePixelData
WidthImage=PeekI(buffer+92) ;ImageWidth
HeightImage=PeekI(buffer+96) ;ImageHeight

DrawImageText(Str(0),image,0)

If GraphicsDepth()=32
 pitch=(((width*8)+127)/128)*16 ;16 bit-aligned
 For iy=1 To height-2
  offset=(pitch*iy) Shl 2
  For ix=1 To width-2
   pixel=BGRA(Rand(255),Rand(255),Rand(255))
   PokeI(PixelData+offset+(ix Shl 2),pixel)
  Next
 Next
ElseIf GraphicsDepth()=16
 pitch=(((width*8)+255)/256)*32 ;32-bit aligned
 For iy=1 To height-2
  offset=(pitch*iy) Shl 1
  For ix=1 To width-2
   pixel=BGR16(Rand(255),Rand(255),Rand(255))
   PokeS(PixelData+offset+(ix Shl 1),pixel)
  Next
 Next
EndIf

While Not KeyDown(1) ;Esc key
 Cls

 Text 0,0,"width="+width+" height="+height+" frames="+frames
 Text 0,12,"image="+image
 Text 0,36,"BufferList="+BufferList
 Text 0,48,"BufferListEnd="+BufferListEnd
 Text 0,60,"numframes="+numframes
 Text 0,84,"buffer="+buffer
 Text 0,96,"pImageBuffer="+pImageBuffer
 Text 0,120,"DDSurface7="+DDSurface7
 Text 0,132,"PixelData="+PixelData
 Text 0,144,"WidthImage="+WidthImage
 Text 0,156,"HeightImage="+HeightImage
 Text 0,168,"pitch="+pitch

 DrawImage image,MouseX()-width,MouseY()-height

 Flip
Wend
End

Function BGRA(blue,green,red,alpha=$FF)
 ;Converts BGRA to a 32-bit value, alpha is optional
 Return ((alpha Shl 24) Or (red Shl 16) Or (green Shl 8) Or blue)
End Function

Function BGR16(blue,green,red)
 ;Converts BGR to a 16-bit value
 Return ((red Shr 3 Shl 11) Or (green Shr 2 Shl 5) Or (blue Shr 3))
End Function

Function DrawImageText(textstr$,image,frame=0)
 ;Draw frame number on image
 Local buffer=GraphicsBuffer()
 SetBuffer ImageBuffer(image,frame)
 ClsColor 255,255,255 : Cls
 Color 255,0,0 : Text 0,0,textstr$
 ClsColor 0,0,0 : Color 255,255,255
 SetBuffer buffer
End Function



markcw(Posted 1+ years ago)

 This example is for b+. It does the same as the b3d example above. You can see the structure of a b+ image is different to b3d.
Code: [Select]
;PeekPoke Example, for BlitzPlus

Include "peekpoke.bb" ;PeekPoke Module

windowx=(ClientWidth(Desktop())-640)/2
windowy=(ClientHeight(Desktop())-480)/2
window=CreateWindow("",windowx,windowy,640,480,0,1+2+32)
canvas=CreateCanvas(0,0,640,480,window)
SetBuffer CanvasBuffer(canvas)

load=0 ;Flag to load or create an image
If load=1
 image=LoadImage("test.bmp")
Else
 width=100
 height=63
 frames=1
 image=CreateImage(width,height,frames)
EndIf

BufferList=PeekI(image+28) ;pImageBufferList
NumFrames=PeekI(image+52) ;ImageFrames

buffer=ImageBuffer(image,0)
pImageBuffer=PeekI(BufferList+(0*4)) ;pImageBuffer[frame]

LockBuffer buffer ;LockBuffer to return a pointer to the pixels
UnlockBuffer buffer
WidthImage=PeekI(buffer+172) ;ImageWidth
HeightImage=PeekI(buffer+176) ;ImageHeight
DDSurface7=PeekI(buffer+192) ;pImageDDSurface7
PixelData=PeekI(buffer+220) ;pImagePixelData

DrawImageText(Str(0),image,0)

If GraphicsDepth()=32
 pitch=(((width*8)+127)/128)*16 ;16 bit-aligned
 For iy=1 To height-2
  offset=(pitch*iy) Shl 2
  For ix=1 To width-2
   pixel=BGRA(Rand(255),Rand(255),Rand(255))
   PokeI(PixelData+offset+(ix Shl 2),pixel)
  Next
 Next
ElseIf GraphicsDepth()=16
 pitch=(((width*8)+255)/256)*32 ;32-bit aligned
 For iy=1 To height-2
  offset=(pitch*iy) Shl 1
  For ix=1 To width-2
   pixel=BGR16(Rand(255),Rand(255),Rand(255))
   PokeS(PixelData+offset+(ix Shl 1),pixel)
  Next
 Next
EndIf

While Not KeyDown(1) ;Esc key
 If WaitEvent(0)=$803 Then End ;Close button
 Cls

 Text 0,0,"width="+width+" height="+height+" frames="+frames
 Text 0,12,"image="+image
 Text 0,36,"BufferList="+BufferList
 Text 0,48,"NumFrames="+NumFrames
 Text 0,72,"buffer="+buffer
 Text 0,84,"pImageBuffer="+pImageBuffer
 Text 0,108,"WidthImage="+WidthImage
 Text 0,120,"HeightImage="+HeightImage
 Text 0,132,"DDSurface7="+DDSurface7
 Text 0,144,"PixelData="+PixelData
 Text 0,156,"pitch="+pitch

 DrawImage image,MouseX(canvas)-width,MouseY(canvas)-height

 FlipCanvas canvas
Wend
End

Function BGRA(blue,green,red,alpha=$FF)
 ;Converts BGRA to a 32-bit value, alpha is optional
 Return ((alpha Shl 24) Or (red Shl 16) Or (green Shl 8) Or blue)
End Function

Function BGR16(blue,green,red)
 ;Converts BGR to a 16-bit value
 Return ((red Shr 3 Shl 11) Or (green Shr 2 Shl 5) Or (blue Shr 3))
End Function

Function DrawImageText(textstr$,image,frame=0)
 ;Draw frame number on image
 Local buffer=GraphicsBuffer()
 SetBuffer ImageBuffer(image,frame)
 ClsColor 255,255,255 : Cls
 Color 255,0,0 : Text 0,0,textstr$
 ClsColor 0,0,0 : Color 255,255,255
 SetBuffer buffer
End Function


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal