flat assembler
Message board for the users of flat assembler.
Index
> Windows > StretchDIBits() call not painting black as expected |
Author |
|
B.Dubious 31 May 2021, 18:26
I started trying to pick up some fasm a while back and after not touching it for a long while I've started trying to pick it up again but I'm not at all sure why my program isn't painting the screen black. I got it working with patblt but I can't figure out why the program isn't painting black.
I have a call to virtualAlloc which gets 2 gigs of memory which looks like this. Code: format PE64 entry main include 'C:\Users\bmowo\Desktop\Tools\fasm\INCLUDE\win64a.inc' include '.\main_data.asm' section '.text' code readable executable main: sub rsp,8 invoke GetModuleHandle,0 mov [WindowClass.hInstance], rax invoke LoadIcon,0,IDI_APPLICATION mov [WindowClass.hIcon],rax mov [WindowClass.hIconSm],rax invoke LoadCursor,0,IDC_ARROW mov [WindowClass.hCursor],rax mov rax, CS_OWNDC or CS_HREDRAW or CS_VREDRAW mov [WindowClass.style], eax invoke RegisterClassExA,WindowClass test rax, rax jz exit invoke CreateWindowExA,0,WindowClassName,WindowTitle, WS_VISIBLE+WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0,0,[WindowClass.hInstance],0 mov [WindowHandle], rax test rax, rax jz exit mov rax, 2*gigabyte mov r10d, MEM_COMMIT or MEM_RESERVE invoke VirtualAlloc,0,eax,r10d,PAGE_READWRITE mov [Memory], rax ; ;clear buffer ; loopCount equ 20000 ; byteOffset equ 4 ; ; mov r8, 0 ; mov r11, [Memory] ;.clearloop: ; mov [r11], dword 0xadde ; ; add r11, byteOffset ; ;add r8, 1 ; inc r8 ; cmp r8, loopCount ; jne .clearloop ; ; restore loopCount ; restore byteOffset mov [GlobalRunning], 1 .main_loop: cmp [GlobalRunning], 0 je exit stdcall Win32MessagePump jmp .main_loop exit: invoke ExitProcess,[Message.wParam] ;------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ ------ proc BlitBuffer locals Width dd 0 Height dd 0 PixelsBase dq 0 DC dq 0 BitmapInfo BITMAPINFO 0 ScreenRect RECT endl ;get window region lea rax, [ScreenRect] invoke GetClientRect, [WindowHandle], rax ;calculate width and height mov ecx, [ScreenRect.bottom] sub ecx, [ScreenRect.top] mov [Height], ecx mov ecx, [ScreenRect.left] sub ecx, [ScreenRect.right] mov [Width], ecx BitmapInfoHeaderSize equ 40 BI_RGB equ 0 mov [BitmapInfo.biSize], BitmapInfoHeaderSize ;sizeof bitmapinfoheader is 40 mov eax, [Width] mov [BitmapInfo.biWidth], eax mov eax, [Height] mov [BitmapInfo.biHeight], eax mov [BitmapInfo.biPlanes], 1 mov [BitmapInfo.biBitCount], 32 mov [BitmapInfo.biCompression], BI_RGB mov [BitmapInfo.biSizeImage], 0 mov [BitmapInfo.biXPelsPerMeter], 0 mov [BitmapInfo.biYPelsPerMeter], 0 mov [BitmapInfo.biClrUsed], 0 mov [BitmapInfo.biClrImportant], 0 mov [BitmapInfo.RGBQUADa], 0 mov [BitmapInfo.RGBQUADb], 0 mov [BitmapInfo.RGBQUADc], 0 mov [BitmapInfo.RGBQUADd], 0 mov rax, [Memory] mov [PixelsBase], rax invoke GetDC, [WindowHandle] mov [DC], rax lea rax, [BitmapInfo] DIB_RGB_COLORS equ 0 invoke StretchDIBits, [DC],0,0,[Width],[Height],0,0,[Width],[Height],[PixelsBase], rax,DIB_RGB_COLORS,SRCCOPY ret endp proc Win32ToggleWindowFullScreen locals WindowStyle dd 0 MonitorInfo MONITORINFO sizeof.MONITORINFO endl GWL_STYLE equ -16 SWP_NOOWNERZORDER equ 0x0200 SWP_FRAMECHANGED equ 0x0020 SWP_NOMOVE equ 0x0002 SWP_NOSIZE equ 0x0001 SWP_NOZORDER equ 0x0004 HWND_TOP equ 0 SWP_FRAMECHANGED equ 0x0020 WS_OVERLAPPEDWINDOW equ 0xcf0000 MONITOR_DEFAULTTOPRIMARY equ 1 invoke GetWindowLongA, [WindowHandle], GWL_STYLE mov [WindowStyle], eax mov rbx, WS_OVERLAPPEDWINDOW and eax, ebx jz .else invoke GetWindowPlacement, [WindowHandle], GlobalWindowPlacement mov r8, rax cmp rax, 1 jb .end invoke MonitorFromWindow,[WindowHandle], MONITOR_DEFAULTTOPRIMARY lea rbx, [MonitorInfo] invoke GetMonitorInfoA,rax,rbx cmp rax, 1 jb .end mov rbx, not WS_OVERLAPPEDWINDOW ;not rbx mov eax, [WindowStyle] and eax, ebx invoke SetWindowLongA, [WindowHandle], GWL_STYLE, eax mov eax, [MonitorInfo.rcMonitor.right] sub eax, [MonitorInfo.rcMonitor.left] mov r10d, [MonitorInfo.rcMonitor.bottom] sub r10d, [MonitorInfo.rcMonitor.top] mov r11, HWND_TOP or SWP_NOOWNERZORDER or SWP_FRAMECHANGED invoke SetWindowPos, [WindowHandle],0,[MonitorInfo.rcMonitor.left],[MonitorInfo.rcMonitor.top],eax,r10d,r11d jmp .end .else: mov eax, [WindowStyle] or rax, WS_OVERLAPPEDWINDOW invoke SetWindowLongA, [WindowHandle],GWL_STYLE,eax invoke SetWindowPlacement,[WindowHandle],GlobalWindowPlacement mov rax, SWP_NOOWNERZORDER or SWP_FRAMECHANGED or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER invoke SetWindowPos,[WindowHandle],0,0,0,0,0,eax .end: ret endp proc Win32MessagePump .while_message: invoke PeekMessageA,Message,[WindowHandle],0,0,PM_REMOVE cmp eax, 0 je .end cmp [Message.message], WM_KEYDOWN je .keydown cmp [Message.message], WM_PAINT je .paint .default: invoke TranslateMessage,Message invoke DispatchMessage,Message jmp .while_message .keydown: stdcall Win32ToggleWindowFullScreen .paint: invoke BeginPaint,[WindowHandle],PaintStruct stdcall BlitBuffer invoke EndPaint,[WindowHandle],PaintStruct jmp .while_message .end: ret endp proc Win32CallbackProc ;hwnd,wmsg,wparam,lparam cmp edx, WM_DESTROY cmp edx, WM_CLOSE cmp edx, WM_QUIT je .close .default: invoke DefWindowProcA,rcx,rdx,r8,r9 jmp .end .close: mov [GlobalRunning], 0 jmp .end .end: ret endp I expected that since the buffer is a large 2 gig zero buffer I should be getting a black screen. But that is not the case. I'm not getting errors from windows and it runs just fine. I have no idea what I'm doing wrong and I really can't progress until I know whats going on here.
Last edited by B.Dubious on 01 Jun 2021, 00:36; edited 3 times in total |
|||||||||||||||||||||
31 May 2021, 18:26 |
|
B.Dubious 31 May 2021, 19:31
I'm fairly sure the allocation succeeded, it's a 64 bit portable executable. I did checks on it with GetLastError and I stepped through with the debugger and rax gets a plausible address which I've tried writing to without crashing. I've tried a number of things and nothing has worked, I just can't see what's wrong with the code at all... but it doesn't work so I must be missing something.
|
|||
31 May 2021, 19:31 |
|
B.Dubious 31 May 2021, 23:26
I've gone through and tidied up a bit. I'll attach the files in case someone fancies having a go at fixing it. I'm still totally confused why I can't get this to draw. I'm going to have to give up on it for tonight at least... I'll try grind at it some more soon.
|
|||
31 May 2021, 23:26 |
|
tthsqe 01 Jun 2021, 11:31
I will have a look.
|
|||
01 Jun 2021, 11:31 |
|
B.Dubious 01 Jun 2021, 17:21
Have any luck? I've been over it again and again and I just don't know what's wrong. I might try do some other programs without graphics and see if I realise anything once I've learned some more fasm programming. Driving me crazy!
|
|||
01 Jun 2021, 17:21 |
|
sinsi 01 Jun 2021, 20:58
Code: lea rax, [BitmapInfo] DIB_RGB_COLORS equ 0 invoke StretchDIBits, [DC],0,0,[Width],[Height],0,0,[Width],[Height],[PixelsBase], rax,DIB_RGB_COLORS,SRCCOPY I think the invoke macro uses RAX, so your initial LEA RAX,[BitmapInfo] is wiped out. Change the two RAXs to R11 and we get a black window. |
|||
01 Jun 2021, 20:58 |
|
tthsqe 01 Jun 2021, 22:47
A few things here:
1. The lea rax, [BitmapInfo] is being clobbered by the invoke StretchDIBits. If I use .. , addr BitmapInfo, .. it works. 2. Probably some rectangles need to be invalidated? 3.Inside the Ein32CallBackProc, there should probably be a je .close after each cmp edx, ... . Otherwise it doest exit when I close it. 4.format PE64 GUI |
|||
01 Jun 2021, 22:47 |
|
B.Dubious 01 Jun 2021, 23:27
Thanks guys, the clobber was the problem. That should have been more obvious to me but I guess I'm pretty daft!
I've followed some of your recommendations tthsqe but I'll have to look up why PE64 GUI. At least now I can get started on my program! That was the most painful time I've ever had getting pixels on the screen to date. I'll need to be careful with macros in future |
|||
01 Jun 2021, 23:27 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.