November 28, 2020, 11:30:36 AM

Author Topic: [bb] Screenshot Functions by Serpent [ 1+ years ago ]  (Read 706 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Screenshot Functions by Serpent [ 1+ years ago ]
« on: June 29, 2017, 12:28:38 AM »
Title : Screenshot Functions
Author : Serpent
Posted : 1+ years ago

Description : It has taken me a ridiculous amount of time to get this working, but here are working screenshot functions for Blitz3D.  There are two different functions because '3D' buffers seem to be structured in memory slightly differently to '2D' buffers.  A description on how to use these functions (if you can be bothered to read it) is at the start of the code.

UPDATE:
Can't believe I forgot this...  .decls required:
Code: [Select]
.lib "gdi32.dll"
BitBlt%(hDestDC%,X%,Y%,nWidth%,nHeight%,hSrcDC,XSrc,YSrc,dwRop)
CreateCompatibleDC%(hdc%)
CreateCompatibleBitmap%(hdc%,Width%,Height%)
SelectObject%(obj%,selobj%)
DeleteDC(hdc%)
DeleteObject(hdc%)
GetDIBitsInt%(hDC%,hbmp%,uStartScan%,uScanLines%,lpvBits%,lpbi*,uUsage%) : "GetDIBits"

.lib "Kernel32.dll"
MoveMemoryObjInt(Destination*,Source%,Length%) : "RtlMoveMemory"

.lib "user32.dll"
GetDC%(hWnd%)
ReleaseDC%(hWnd%,hDC%)


Code :
Code: BlitzBasic
  1. ;  WORKING SCREENSHOT FUNCTIONS
  2. ;  Author:  James (aka Serpent)
  3. ;
  4. ;  Grabs top left corner of screen.
  5. ;
  6. ;  Usage:
  7. ;  Screenshot2DBuffer(DestinationBuffer, Width, Height)
  8. ;  Screenshot3DBuffer(DestinationBuffer, Width, Height)
  9. ;
  10. ;  DestinationBuffer - the buffer that will eventually be written to.  Can be any buffer (FrontBuffer, BackBuffer, ImageBuffer, TextureBuffer)!
  11. ;  Return Value - False if a parameter is 0, otherwise True.
  12. ;
  13. ;  Note: There is a difference between the two functions!  You must use the Screenshot2DBuffer function for '2D' buffers (i.e. ImageBuffers
  14. ;        and the FrontBuffer and BackBuffer in a 2D Graphics Mode), and you must use the Screenshot3DBuffer function for '3D' buffers
  15. ;        (i.e. TextureBuffers and the FrontBuffer and BackBuffer in a 3D Graphics Mode).  There is a slight difference regarding the structure in
  16. ;        memory of these buffers.  Although I do not know what it is I have worked around it.  3D buffers require a power of 2 size and 2D buffers
  17. ;        a width divisible by 16.  The functions take care of this - you can use any size for your buffer as long as you use the correct function.
  18. ;
  19. ;  MAKE SURE THAT YOU GIVE THE FUNCTION BUFFERS THAT ARE UNLOCKED, NOT LOCKED.  The functions lock and unlock buffers as necessary.
  20. ;  Although my testing has found that locking a buffer twice then unlocking it twice works alright, it may cause unexpected results.  If you lock
  21. ;  the buffer then the functions won't get what they expect.
  22. ;
  23. ;
  24. ;
  25. ;  Timing - For 2D buffers on my computer:
  26. ;
  27. ;  < 40 ms for a 1680 by 1050 screenshot (almost good enough for 30 screenshots per second at this resolution)
  28. ;  18-19 ms for an 800 by 600 screenshot
  29. ;
  30. ;
  31. ;
  32. ;  Note:  It is probably useful to call the GetSystemMetrics() function (user32.dll) to find the screen width and height.
  33. ;
  34. ;
  35. ;
  36. ;  e.g. - copy entire screen to BackBuffer:
  37. ;
  38. ;  Screenshot BackBuffer(), GetSystemMetrics(0), GetSystemMetrics(1)
  39. ;
  40. ;
  41. ;  .decls file (not needed for screenshot function, but useful - GetSystemMetrics):
  42. ;  ---------------------------
  43. ;  .lib "user32.dll"
  44. ;  GetSystemMetrics%(nIndex%)
  45. ;  ---------------------------
  46. ;
  47. ;
  48. ;
  49. ;  Note:  Keep Width and Height parameters positive, otherwise you might experience vertical or horizontal flipping of the
  50. ;         image - unless you want to do this for some reason.
  51.  
  52.  
  53.  
  54. Function Screenshot2DBuffer(DestinationBuffer,BufferWidth,BufferHeight)
  55.        
  56.         If DestinationBuffer = 0 Or BufferWidth = 0 Or BufferHeight = 0 Then Return False
  57.        
  58.         OriginalBufferWidth = BufferWidth
  59.         BufferWidth = BufferWidth / 16
  60.         If BufferWidth * 16 <> OriginalBufferWidth Then BufferWidth = (BufferWidth + 1) * 16 Else BufferWidth = OriginalBufferWidth
  61.        
  62.         hDC = GetDC(0)
  63.         hMemDC= CreateCompatibleDC(hdc)
  64.         hMemBmp= CreateCompatibleBitmap(hdc,BufferWidth,BufferHeight)
  65.        
  66.         bmi = CreateBank(48)
  67.         PokeByte bmi,0,44
  68.         PokeInt bmi,4,BufferWidth
  69.         PokeInt bmi,8,-BufferHeight
  70.         PokeByte bmi,12,1
  71.         PokeByte bmi,14,32
  72.        
  73.         SelectObject hMemDC, hMemBmp
  74.         BitBlt hMemDC, 0, 0, BufferWidth, BufferHeight, hDC, 0, 0, $00CC0020
  75.        
  76.         If BufferWidth = OriginalBufferWidth Then
  77.        
  78.                 LockBuffer DestinationBuffer
  79.                 LocBnk = CreateBank(76)
  80.                 MoveMemoryObjInt(LocBnk,DestinationBuffer,76)
  81.                 Loc = PeekInt(LocBnk,72)
  82.                 FreeBank LocBnk
  83.                 GetDIBitsInt hDC,hMemBmp,0,BufferHeight,Loc,bmi,0
  84.                 UnlockBuffer DestinationBuffer
  85.                
  86.         Else
  87.                
  88.                 TemporaryImage = CreateImage(BufferWidth,BufferHeight)
  89.                 TemporaryBuffer = ImageBuffer(TemporaryImage)
  90.                 LocBnk = CreateBank(76)
  91.                 LockBuffer TemporaryBuffer
  92.                 MoveMemoryObjInt(LocBnk,TemporaryBuffer,76)
  93.                 Loc = PeekInt(LocBnk,72)
  94.                 FreeBank LocBnk
  95.                 GetDIBitsInt hDC,hMemBmp,0,BufferHeight,Loc,bmi,0
  96.                 UnlockBuffer TemporaryBuffer
  97.                 CopyRect 0,0,OriginalBufferWidth,BufferHeight,0,0,TemporaryBuffer,DestinationBuffer
  98.                
  99.         EndIf
  100.        
  101.         ReleaseDC 0, hDC
  102.         DeleteDC hMemDC
  103.         DeleteObject hMemBmp
  104.        
  105.         FreeBank bmi
  106.         Return True
  107.        
  108. End Function
  109.  
  110. Function Screenshot3DBuffer(DestinationBuffer,BufferWidth,BufferHeight)
  111.        
  112.         If DestinationBuffer = 0 Or BufferWidth = 0 Or BufferHeight = 0 Then Return False
  113.        
  114.         OriginalBufferWidth = BufferWidth
  115.         Shifts = -1
  116.         Repeat
  117.                 BufferWidth = BufferWidth Shr 1
  118.                 Shifts = Shifts + 1
  119.         Until BufferWidth = 0
  120.         BufferWidth = 1 Shl Shifts
  121.        
  122.         If BufferWidth < OriginalBufferWidth Then BufferWidth = BufferWidth Shl 1
  123.        
  124.         hDC = GetDC(0)
  125.         hMemDC= CreateCompatibleDC(hdc)
  126.         hMemBmp= CreateCompatibleBitmap(hdc,BufferWidth,BufferHeight)
  127.        
  128.         bmi = CreateBank(48)
  129.         PokeByte bmi,0,44
  130.         PokeInt bmi,4,BufferWidth
  131.         PokeInt bmi,8,-BufferHeight
  132.         PokeByte bmi,12,1
  133.         PokeByte bmi,14,32
  134.        
  135.         SelectObject hMemDC, hMemBmp
  136.         BitBlt hMemDC, 0, 0, BufferWidth, BufferHeight, hDC, 0, 0, $00CC0020
  137.        
  138.         If BufferWidth = OriginalBufferWidth Then
  139.                
  140.                 LockBuffer DestinationBuffer
  141.                 LocBnk = CreateBank(76)
  142.                 MoveMemoryObjInt(LocBnk,DestinationBuffer,76)
  143.                 Loc = PeekInt(LocBnk,72)
  144.                 FreeBank LocBnk
  145.                 GetDIBitsInt hDC,hMemBmp,0,BufferHeight,Loc,bmi,0
  146.                 UnlockBuffer DestinationBuffer
  147.                
  148.         Else
  149.                
  150.                 TemporaryImage = CreateImage(BufferWidth,BufferHeight)
  151.                 TemporaryBuffer = ImageBuffer(TemporaryImage)
  152.                 LocBnk = CreateBank(76)
  153.                 LockBuffer TemporaryBuffer
  154.                 MoveMemoryObjInt(LocBnk,TemporaryBuffer,76)
  155.                 Loc = PeekInt(LocBnk,72)
  156.                 FreeBank LocBnk
  157.                 GetDIBitsInt hDC,hMemBmp,0,BufferHeight,Loc,bmi,0
  158.                 UnlockBuffer TemporaryBuffer
  159.                 CopyRect 0,0,OriginalBufferWidth,BufferHeight,0,0,TemporaryBuffer,DestinationBuffer
  160.                
  161.         EndIf
  162.        
  163.         ReleaseDC 0, hDC
  164.         DeleteDC hMemDC
  165.         DeleteObject hMemBmp
  166.        
  167.         FreeBank bmi
  168.         Return True
  169.        
  170. End Function


Comments :


_PJ_(Posted 1+ years ago)

 <div class="quote"> ;  .decls file (not needed for screenshot function, but useful - GetSystemMetrics):;  ---------------------------;  .lib "user32.dll";  GetSystemMetrics%(nIndex%);  --------------------------- </div>That's all well and good, but what about decls for the other functions?


Serpent(Posted 1+ years ago)

 Oh sry - forgot about .decls for everything...  I'll update it in a sec.


_PJ_(Posted 1+ years ago)

 :) Thanks. I did find a list of GDI decls around here somewhere, but at the time I didnt know where the functions were from!


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal