In practice, WORD size would be sufficient: 65535 pixels at max, still difficult to achieve with current screens! Therefore, in order to save RAM, it would be extremely convenient if one could use the SMALL_RECT structure instead of the RECT structure.
Below a simple GUI application that uses the ultra-fast SmallRectToRect Subroutine to convert SMALL_RECTs to ordinary RECTs on the fly. There are not yet any timing routines implemented, but it should be easy to add. RAM usage can be monitored in Task Manager. WARNING: You will probably not see significant effects on speed and RAM usage for small element counts. Increase the #define to, say, ten Millions, and the effect on RAM usage, as compared to a traditional wasteful RECT array, should be really significant. Attention, it might not work with CPUs older than ten years.
Note this is Win32 only, although SmallRectToRect might work on Linux, too.
Code: Select all
#Include "windows.bi"
#define elements 20
Dim Shared smrc(0 To elements-1) As SMALL_RECT
Sub SmallRectToRect naked (pDest as RECT ptr, pSrc as SMALL_RECT ptr)
asm
#ifndef sMask
.data
.align 16
sMask:
.quad 0xffff0302ffff0100, 0xffff0706ffff0504
.section .text
#endif
mov eax, [esp+4] ' [pDest]
mov edx, [esp+8] ' [pSrc]
movlps xmm0, [edx]
pshufb xmm0, sMask
movups [eax], xmm0
ret 4
end asm
end sub
Function WndProc(hWnd As HWND, msg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
Dim As integer ct
Dim As RECT rc
Dim As PAINTSTRUCT ps
Dim As HANDLE PtDC
Select Case (msg)
Case WM_PAINT
PtDC=BeginPaint(hWnd, @ps)
For ct=0 To elements-1
SmallRectToRect(@rc, @smrc(ct))
FrameRect(PtDC, @rc, GetStockObject(GRAY_BRUSH))
Next
EndPaint(hWnd, @ps)
Case WM_KEYDOWN
if wParam=VK_ESCAPE then SendMessage(hWnd, WM_CLOSE, 0, 0)
Case WM_SIZE
GetClientRect(hWnd, @rc)
For ct=0 To elements-1 ' create the artwork
smrc(ct).Left=Rnd*100+5
smrc(ct).Top=Rnd*100+5
smrc(ct).Right=smrc(ct).Left+Rnd*rc.right*0.666+10
smrc(ct).Bottom=smrc(ct).Top+Rnd*rc.bottom*0.666+10
Next
Case WM_DESTROY
PostQuitMessage(0)
End Select
return DefWindowProc(hwnd, msg, wParam, lParam)
End Function
Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
Dim As WNDCLASSEX wc
Dim As MSG msg
Dim As string classname="FbGui"
wc.cbSize = sizeof(WNDCLASSEX)
wc.hbrBackground = COLOR_WINDOW+1
wc.hCursor = LoadCursor(0, IDC_ARROW)
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION)
wc.hIconSm = wc.hIcon
wc.hInstance = hInstance
wc.lpfnWndProc = @WndProc
wc.lpszClassName = StrPtr(classname)
wc.style = CS_HREDRAW Or CS_VREDRAW
RegisterClassEx(@wc)
if CreateWindowEx(0, wc.lpszClassName, "Hello SMALL_RECT World",_
WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
(GetSystemMetrics(SM_CYSCREEN) / 2) - 150, 300, 300, 0, 0, hInstance, 0)=0 then
MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
return 0
End If
While GetMessage(@msg, 0, 0, 0)
TranslateMessage(@msg)
DispatchMessage(@msg)
Wend
return msg.wParam
End Function
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)