Author Topic: Union structure  (Read 1326 times)

0 Members and 1 Guest are viewing this topic.

Aurel

  • Guest
Union structure
« on: January 25, 2020, 03:07:22 AM »
Hello Charles.. and all orhers

I need small help about how to properly translate this C code to o2

struct pixel {
  union {
    struct {
      /* 'a' unused, used for 32-bit alignment,
       * could also be used to store pixel alpha
       */
      unsigned char b, g, r, a;
    };
    int val;
  };
  pixel() {
    val = 0;
  }
};


thanks

Charles Pegge

  • Guest
Re: Union structure
« Reply #1 on: January 25, 2020, 03:40:23 AM »
Hi Aurel,

It simplifies to:
Code: [Select]
type pixel
  ubyte b,g,r,a
  =
  int val
end type

and unlike C, All variables are automtically initialised to nul.


Aurel

  • Guest
Re: Union structure
« Reply #2 on: January 25, 2020, 04:21:50 AM »
Hi Charles
..and thank you , i am trying to convert one simple but fast gdi dib example , i will post it here
 ;)

Aurel

  • Guest
Re: Union structure
« Reply #3 on: January 25, 2020, 09:30:11 AM »
Hi Charles
I get really strange error about parameter mismatch
for gdi function CreateDIBSection()
in declaration i have exactly 6 params also as in setting subroutine
i am asking you what I made wrong ?

Code: [Select]
'fast GDI with DIB section
$ filename "FastGDI.exe"
include "RTL32.inc"
include "awinh037.inc"
#lookahead

' struct pixel
type PIXEL
  ubyte b
  ubyte g
  ubyte r
  ubyte a
  =
  int value
end type

type BITMAPINFOHEADER
DWORD biSize
LONG  biWidth
LONG  biHeight
WORD  biPlanes
WORD  biBitCount
DWORD biCompression
DWORD biSizeImage
LONG  biXPelsPerMeter
LONG  biYPelsPerMeter
DWORD biClrUsed
DWORD biClrImportant
end type

type RGBQUAD
BYTE rgbBlue
BYTE rgbGreen
BYTE rgbRed
BYTE rgbReserved
end type

type BITMAPINFO
  BITMAPINFOHEADER bmiHeader
  RGBQUAD bmiColors
end type

! CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long,byref  pBitmapInfo As BITMAPINFO, ByVal un As Long, ByVal lplpVoid As Long, ByVal handle As Long, ByVal dw As Long) As Long
% DIB_RGB_COLORS  = 0

' Window client size
int width = 375
int height = 375
% BI_RGB = 0
' Target fps, though it's hard to achieve this fps
' without extra timer functionality unless you have
' a powerfull processor. Raising this value will
' increase the speed, though it will use up more CPU.
int fps = 50
' Global Windows/Drawing variables
INT hbmp
INT hTickThread
INT hwnd
INT hdc
INT hdcMem
INT wstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
' Pointer to pixels (will automatically have space allocated by CreateDIBSection
PIXEL pixels
INT win
'reg class & create window using awinh037.inc ---------------------------------------
win = SetWindow("Fast_GDI", 300, 200, width, height, 0, wstyle)
'------------------------------------------------------------------------------------
RECT rcClient, rcWindow
POINTAPI ptDiff
 ' Get window and client sizes
  GetClientRect( win, rcClient )
  GetWindowRect( win, rcWindow )
 ' Find offset between window size and client size
  ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right
  ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom

 ' Resize client
  MoveWindow( win, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, -1)
  UpdateWindow( win )


' wmsg loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  while GetMessage(wm, 0, 0, 0)
        TranslateMessage wm
        DispatchMessage wm
  wend
' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Function WndProc( sys hwnd, wmsg, wParam, lParam) as sys callback

SELECT hwnd
  CASE win
  select wmsg
    case WM_CREATE     
       ' MakeSurface( hwnd )
           
    case WM_PAINT     
        PAINTSTRUCT ps
        hdc = BeginPaint( win, ps )
        ' Draw pixels to window when window needs repainting
        BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
        EndPaint( win, ps )
           
    case WM_CLOSE 
        DestroyWindow( win )

    case WM_DESTROY
        'TerminateThread( hTickThread, 0 )
        PostQuitMessage( 0 )
     
    'case else
      'return DefWindowProc( hwnd, wmsg, wParam, lParam )

  end select
END SELECT
Return DefWindowProc(hwnd,wMsg,wParam,lParam)
 
End Function

'..................................................................

SUB MakeSurface(INT wnd)
  ' Use CreateDIBSection to make a HBITMAP which can be quickly
  '  blitted to a surface while giving 100% fast access to pixels before blit.
  ' Desired bitmap properties
  BITMAPINFOHEADER bmi
  bmi.biSize = sizeof(BITMAPINFOHEADER)
  bmi.biWidth = width
  bmi.biHeight =  -height ' Order pixels from top to bottom
  bmi.biPlanes = 1
  bmi.biBitCount = 32 ' last byte not used, 32 bit for alignment
  bmi.biCompression = BI_RGB
  bmi.biSizeImage = 0
  bmi.biXPelsPerMeter = 0
  bmi.biYPelsPerMeter = 0
  bmi.biClrUsed = 0
  bmi.biClrImportant = 0

BITMAPINFO bmci
 bmci.bmiColors[0].rgbRed = 0
 bmci.bmiColors[0].rgbGreen = 0
 bmci.bmiColors[0].rgbBlue = 0
 bmci.bmiColors[0].rgbReserved = 0
  hdc = GetDC( win )
  lPtr as long
  ' Create DIB section to always give direct access to pixels
  hbmp = CreateDIBSection( hdc, bmi, DIB_RGB_COLORS, pixels , 0, 0 )
  DeleteDC( hdc )
  ' Create a new thread to use as a timer
  'hTickThread = CreateThread( NULL, NULL, &tickThreadProc, 0, 0, 9 )

END SUB

Aurel

  • Guest
Re: Union structure
« Reply #4 on: January 25, 2020, 09:31:54 AM »
o2 complain under this line : pass 2

hbmp = CreateDIBSection( hdc, bmi, DIB_RGB_COLORS, pixels , 0, 0 )

Charles Pegge

  • Guest
Re: Union structure
« Reply #5 on: January 25, 2020, 02:16:11 PM »
It should work using corewin

this will include gdi.inc

Aurel

  • Guest
Re: Union structure
« Reply #6 on: January 26, 2020, 12:52:33 PM »
Well not work as i think with all possible problems with pointers and adresses
i really become confused.
I think ( only think) that createDIBsection well respond - not crush
CreateThread() not crush if is in SUSSPENDED mode ...hm.. never use this function before
very complex program for translation ...so if anyone have idea how this might work let me known..

i will try reconfigure program to work without Threading and without DIB

here is what i done today...in few hours  ::)
Of course you don't need to use awinho37.inc .... it can be created directly with little bit more code
(i was tested awinh is not in any conflict with this two functions )

Code: [Select]
'fast GDI with DIB section
$ filename "FastGDI.exe"
include "RTL32.inc"
include "awinh037.inc"
#lookahead

' struct pixel
type PIXEL
  ubyte b,g,r,a
  =
  int value
end type

type BITMAPINFOHEADER
LONG biSize
LONG  biWidth
LONG  biHeight
INTEGER  biPlanes
INTEGER  biBitCount
LONG biCompression
LONG biSizeImage
LONG  biXPelsPerMeter
LONG  biYPelsPerMeter
LONG biClrUsed
LONG biClrImportant
end type

type RGBQUAD
BYTE rgbBlue
BYTE rgbGreen
BYTE rgbRed
BYTE rgbReserved
end type

type BITMAPINFO
  BITMAPINFOHEADER bmiHeader
  RGBQUAD bmiColors
end type

Declare Function CreateDIBSection Lib "gdi32.dll" (ByVal hDC As Long, *pBitmapInfo As BITMAPINFO, ByVal usage As UINT, *lplpVoid As sys, ByVal hSection As Long, ByVal offset As Long) As Long
Declare Function CreateThread Lib "kernel32.dll" (byval lpThreadAttributes As Any, ByVal dwStackSize As Long,byval pStartAddress As long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Declare Function TerminateThread Lib "kernel32.dll" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
% DIB_RGB_COLORS  = 0

' Window client size
int width = 375
int height = 375
% BI_RGB = 0
' Target fps, though it's hard to achieve this fps
' without extra timer functionality unless you have
' a powerfull processor. Raising this value will
' increase the speed, though it will use up more CPU.
int fps = 50
' Global Windows/Drawing variables
INT hbmp
INT hTickThread
INT hwnd
INT hdc
INT hdcMem
INT wstyle = WS_MINMAXSIZE or WS_CLIPCHILDREN
' Pointer to pixels (will automatically have space allocated by CreateDIBSection
PIXEL *pixels
INT win
Dim lpThreadID As Long
'reg class & create window using awinh037.inc ---------------------------------------
win = SetWindow("Fast_GDI", 300, 200, width, height, 0, wstyle)
'------------------------------------------------------------------------------------
RECT rcClient, rcWindow
POINTAPI ptDiff
 ' Get window and client sizes
  GetClientRect( win, rcClient )
  GetWindowRect( win, rcWindow )
 ' Find offset between window size and client size
  ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right
  ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom


'MakeSurface( win)
 ' Resize client
  MoveWindow( win, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, -1)
  UpdateWindow( win )


' wmsg loop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  while GetMessage(wm, 0, 0, 0)
        TranslateMessage wm
        DispatchMessage wm
  wend
' <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Function WndProc( sys hwnd, wmsg, wParam, lParam) as sys callback
win=hwnd

'SELECT hwnd
  'CASE win
  select wmsg
    case WM_CREATE     
        MakeSurface(win )
           
    case WM_PAINT     
        PAINTSTRUCT ps
        hdc = BeginPaint( win, ps )
         'draw text to screen DC
              TextOut hdc, 100,100, "FAST_GDI", 8
               'SetPixel ( hdc, 200, 200, RGB( 100, 0,200) )
        ' Draw pixels to window when window needs repainting
        BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
        EndPaint( win, ps )
           
    case WM_CLOSE 
        DestroyWindow( win )

    case WM_DESTROY
        TerminateThread( hTickThread, 0 )
        PostQuitMessage( 0 )
  end select
'END SELECT
Return DefWindowProc(hwnd,wMsg,wParam,lParam)
 
End Function

'..................................................................

SUB MakeSurface(INT wnd)
  ' Use CreateDIBSection to make a HBITMAP which can be quickly
  '  blitted to a surface while giving 100% fast access to pixels before blit.
  ' Desired bitmap properties
  BITMAPINFOHEADER bmi
  bmi.biSize = sizeof bmi
  bmi.biWidth = width
  bmi.biHeight =  -height ' Order pixels from top to bottom
  bmi.biPlanes = 1
  bmi.biBitCount = 32 ' last byte not used, 32 bit for alignment
  bmi.biCompression = BI_RGB
  bmi.biSizeImage = 0
  bmi.biXPelsPerMeter = 0
  bmi.biYPelsPerMeter = 0
  bmi.biClrUsed = 0
  bmi.biClrImportant = 0

BITMAPINFO bmci
 bmci.bmiColors[0].rgbRed = 0
 bmci.bmiColors[0].rgbGreen = 0
 bmci.bmiColors[0].rgbBlue = 0
 bmci.bmiColors[0].rgbReserved = 0
  hdc = GetDC( win )
 
  ' Create DIB section to always give direct access to pixels
  hbmp = CreateDIBSection( hdc,byval &bmi, DIB_RGB_COLORS,byval &pixels , 0, 0 )
  DeleteDC( hdc )
  ' Create a new thread to use as a timer
  ' Private Const CREATE_SUSPENDED = &H4
  hTickThread = CreateThread(ByVal 0&, ByVal 0& ,byval  &tickThreadProc , byval 0&, &H4 , lpThreadID)
  print "TickTHREAD:" str hTickThread

END SUB

SUB tickThreadProc(int handle)
   int on
print "TH-OK"
  ' Give plenty of time for main thread to finish setting up
  Sleep( 50 )
  ShowWindow( hwnd, SW_SHOW )
  ' Retrieve the window's DC
  hdc = GetDC( hwnd )
  ' Create DC with shared pixels to variable 'pixels'
  hdcMem = CreateCompatibleDC( hdc )
  hbmOld = SelectObject( hdcMem, hbmp )
  'Milliseconds to wait each frame
  int delay = 100 / fps
  for on = 0 to 100
    ' Do stuff with pixels
    onFrame()

    ' Draw pixels to window
    BitBlt( hdc, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY )
    ' Wait
    Sleep( delay )
  next on

  SelectObject( hdcMem, hbmOld )
  DeleteDC( hdc )
END SUB

SUB onFrame()
  ' This is where all the drawing takes place
  PIXEL *p
  ' +0.005 each frame
  static float frameOffset = 0
  float px '% of the way across the bitmap
  float py  '% of the way down the bitmap
  for x = 0 to width
    for y = 0 to height
      p = y * width + x
      px = (x) / (width)
      py = (y) / (height)
      p.r = ubyte(((cos(px + frameOffset * 10) / sin(py + frameOffset)) * cos(frameOffset * 3) * 10) * 127 + 127)
      p.g = 100
      p.b = 255
         SetPixel ( hdc, px, py, RGB(p.r, p.g, p.b) )
    next y
  next y
  frameOffset += 0.05
end sub

Charles Pegge

  • Guest
Re: Union structure
« Reply #7 on: January 27, 2020, 01:47:28 AM »
INTEGER should be replaced with WORD

MS definition:
Code: [Select]
typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;
  LONG  biWidth;
  LONG  biHeight;
  WORD  biPlanes;
  WORD  biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG  biXPelsPerMeter;
  LONG  biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;