flat assembler
Message board for the users of flat assembler.

Index > Windows > Why this code does not work?

Author
Thread Post new topic Reply to topic
A$M



Joined: 29 Feb 2012
Posts: 94
A$M
Hello!

I made this code that should paint a pixel somewhere in the window, but it is not working.

Code:
format PE GUI 4.0
entry start

include "win32a.inc"

section '.text' code readable executable
 start:
    ;mov [wc.lpfnWndProc], WindowProc
    invoke GetModuleHandle, 0
    mov [wc.hInstance], eax
    invoke LoadIcon, 0, IDI_APPLICATION
    mov [wc.hIcon], eax
    mov [wc.hIconSm], eax
    invoke LoadCursor, 0, IDC_CROSS
    mov [wc.hCursor], eax
    invoke GetStockObject, BLACK_BRUSH
    mov [wc.hbrBackground], eax

    invoke RegisterClassEx, wc, 0
    invoke CreateWindowEx, 0, _class, _title, WS_OVERLAPPEDWINDOW+WS_VISIBLE, 100, 100, 500, 500, 0, 0, [wc.hInstance], 0
    test eax, eax
    jz winerror
    ;invoke ShowWindow, [wc.hInstance], [nCmdShow]
 msg_loop:
    invoke GetMessage, wMsg, 0, 0, 0
    cmp eax,1
    jb exit
    jne msg_loop
    invoke TranslateMessage, wMsg
    invoke DispatchMessage, wMsg
 jmp msg_loop

 winerror:
    invoke MessageBox, 0, WinError, 0, MB_ICONERROR+MB_OK
 exit:
    mov eax, [wMsg.wParam]
    invoke ExitProcess, [wMsg.wParam]

 proc WindowProc uses ebx esi edi, hWnd, uMsg, wParam, lParam
    mov eax, [uMsg]
    cmp eax, WM_CREATE
    je wmCreate
    cmp eax, WM_TIMER
    je wmTimer
    cmp eax, WM_PAINT
    je wmPaint
    cmp eax, WM_CLOSE
    je wmClose
    cmp eax, WM_DESTROY
    je wmDestroy
    invoke DefWindowProcA, [hWnd], [uMsg], [wParam], [lParam]
    ret

 wmCreate:
    invoke SetTimer, [hWnd], 1, 20, 0
    ret

 wmTimer:
    invoke InvalidateRect, [hWnd], 0, 0
    ret

 wmPaint:
    invoke BeginPaint, [hWnd], psPaint
    mov [hDC], eax

    invoke CreateCompatibleDC, [hDC]
    mov [memDC], eax

    invoke CreateDIBSection, [hDC], BITMAPINFO, 0, pDIBSCR, 0, 0
    mov [hDIBSCR], eax

    invoke SelectObject, [hDC], [hDIBSCR]
    mov [hOldDIB], eax

    invoke CreateCompatibleDC, [hDC]
    mov [hBackDC], eax
    invoke CreateCompatibleBitmap, [hDC], 640, 480
    mov [bufBMP], eax
    invoke SelectObject, [hBackDC], [bufBMP]
    mov [hOldBmp], eax

    mov edi, [pDIBSCR]
    mov dword[edi+320*240*4], 0FFFFFFh

    invoke BitBlt, [hBackDC], 0, 0, 640, 480, [memDC], 0, 0, SRCCOPY
    invoke BitBlt, [hDC], 0, 0, 640, 480, [hBackDC], 0, 0, SRCCOPY

    invoke    SelectObject, [hBackDC], [hOldBmp]
    invoke    DeleteObject, [bufBMP]
    invoke    DeleteDC, [hBackDC]

    invoke    SelectObject, [memDC], [hOldDIB]
    invoke    DeleteObject, [hDIBSCR]
    invoke    DeleteDC, [memDC]

 ;   invoke Ellipse, [hDC], 10, 10, 200, 200

    invoke EndPaint, [hWnd], psPaint
    ret

 wmClose:
    invoke DestroyWindow, [hWnd]
    ret

 wmDestroy:
    invoke PostQuitMessage, WM_QUIT
    ret

 endp


section '.data' data readable writeable
 wc WNDCLASSEX wcend-wc, 0, WindowProc, 0, 0, 0, 0, 0, 0, 0, _class, 0
 wcend:
 _class db "MAIN",0
 _title db "Teste de janela",0
 WinError db "Não foi possível criar a janela",0
 BITMAPINFO    BITMAPINFOHEADER sizeof.BITMAPINFOHEADER,\  ; biSize
                                    640,\                      ; biWidth
                                    480,\                      ; biHeight
                                    1,\                        ; biPlanes       
                                    32,\                       ; biBitCount
                                    0,\                        ; biCompression  
                                    0,\                        ; biSizeImage
                                    0, \                       ; biXPelsPerMeter
                                    0, \                       ; biYPelsPerMeter
                                    0, \                       ; biClrUsed      
                                    0                          ; biClrImportant

section '.bss' data readable writeable
 wMsg MSG
 psPaint PAINTSTRUCT
 hDC dd ?
 memDC dd ?
 pDIBSCR dd ?
 hDIBSCR dd ?
 hOldDIB dd ?
 hBackDC dd ?
 bufBMP dd ?
 hOldBmp dd ?

section '.idata' import data readable writeable
 library kernel32, "KERNEL32.DLL",\
         user32, "USER32.DLL",\
         gdi32, "GDI32.DLL"

 include "api\kernel32.inc"
 include "api\user32.inc"
 include "api\gdi32.inc"

;section '.rsrc' resource data readable

    


I made it from this code (http://board.flatassembler.net/download.php?id=6195), with some changes. But it does not work. Does anyone know why?
Post 11 Sep 2013, 18:32
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 19:57; edited 1 time in total
Post 11 Sep 2013, 20:52
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
A$M:
Why use such complex way to draw a pixel?
Simply call SetPixel().

Or you are trying to put a pixel first on the bitmap and then on screen?
If so, then why DIB?

Can you explain in detail what is exactly needed?
Post 11 Sep 2013, 21:38
View user's profile Send private message Send e-mail Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M
AsmGuru62 wrote:
A$M:
Why use such complex way to draw a pixel?
Simply call SetPixel().

Or you are trying to put a pixel first on the bitmap and then on screen?
If so, then why DIB?

Can you explain in detail what is exactly needed?


Well... In fact, we can ignore this code. I want to learn how to make graphics in windows in the same way as would be done in DOS.
Example:
Code:
mov [0A0000h+160+100*320], 15    ; White pixel at 160, 100    

Using GDI, how could I get them?

Ps.: SetPixel isn't very slow?
Post 12 Sep 2013, 14:46
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
I see...

SetPixel is indeed slow, so if you want to use to draw a lot of pixels -- then try to draw (using SetPixel) in memory and then BitBlt on screen.

In DOS to draw a line you must use pixels and Brezenham logic, but in Windows -- there is an API to draw a line. In fact,
API has everything you need to draw: polygons, circles (ellipses), etc.

If your output to screen is too loaded - a lot of objects to be painted, use memory DC as you did in that code and then after drawing on memory DC -- BitBlt it to a screen DC.
Tell me if you want an example of something to be painted and I will try to make a code sample.
Post 12 Sep 2013, 16:03
View user's profile Send private message Send e-mail Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M
My new code:
Code:
format PE GUI 4.0
entry start

include "win32a.inc"

section '.text' code readable executable
 start:
    invoke GetModuleHandle, 0
    mov [wc.hInstance], eax
    invoke LoadIcon, 0, IDI_APPLICATION
    mov [wc.hIcon], eax
    mov [wc.hIconSm], eax
    invoke LoadCursor, 0, IDC_CROSS
    mov [wc.hCursor], eax
    invoke GetStockObject, BLACK_BRUSH
    mov [wc.hbrBackground], eax

    invoke RegisterClassEx, wc, 0
    invoke CreateWindowEx, 0, _class, _title, WS_OVERLAPPED+WS_SYSMENU+WS_VISIBLE, 100, 100, 640, 480, 0, 0, [wc.hInstance], 0
    test eax, eax
    jz winerror
 msg_loop:
    invoke GetMessage, wMsg, 0, 0, 0
    cmp eax, 1
    jb exit
    jne msg_loop
    invoke TranslateMessage, wMsg
    invoke DispatchMessage, wMsg
 jmp msg_loop

 winerror:
    invoke MessageBox, 0, WinError, 0, MB_ICONERROR+MB_OK
 exit:
    mov eax, [wMsg.wParam]
    invoke ExitProcess, [wMsg.wParam]

 proc WindowProc uses ebx esi edi, hWnd, uMsg, wParam, lParam
    mov eax, [uMsg]
    cmp eax, WM_CREATE
    je wmCreate
    cmp eax, WM_TIMER
    je wmTimer
    cmp eax, WM_PAINT
    je wmPaint
    cmp eax, WM_CLOSE
    je wmClose
    cmp eax, WM_DESTROY
    je wmDestroy
    invoke DefWindowProcA, [hWnd], [uMsg], [wParam], [lParam]
    ret

 wmCreate:
    invoke SetTimer, [hWnd], 1, 20, 0
    invoke GetDC, [hWnd]
    mov [hDC], eax
    invoke CreateCompatibleDC, [hDC]  ; DC de memória
    mov [hMemDC], eax
    invoke CreateDIBSection, [hDC], BITMAPINFO, 0, pDIBSCR, 0, 0  ; Tela
    mov [hDIBSCR], eax
    invoke SelectObject, [hMemDC], [hDIBSCR]
    ret

 wmTimer:
    mov eax, [color]
    cmp eax, 0FFFFFFh
    jne @f
    mov [color], 080h
@@: add [color], 010101h
    invoke InvalidateRect, [hWnd], 0, 0
    ret

 wmPaint:
    invoke BeginPaint, [hWnd], psPaint
    mov [hDC], eax

    mov edi, [pDIBSCR]
    mov ecx, 640*480
    mov eax, [color]
    rep stosd

    invoke BitBlt, [hDC], 0, 0, 640, 480, [hMemDC], 0, 0, SRCCOPY

    invoke EndPaint, [hWnd], psPaint
    ret

 wmClose:
    invoke SelectObject, [hMemDC], [hDIBSCR]
    mov [oDIBSCR], eax
    invoke DeleteObject, [oDIBSCR]
    invoke DeleteDC, [hMemDC]

    invoke DestroyWindow, [hWnd]
    ret

 wmDestroy:
    invoke PostQuitMessage, WM_QUIT
    ret

 endp


section '.data' data readable writeable
 wc WNDCLASSEX wcend-wc, 0, WindowProc, 0, 0, 0, 0, 0, 0, 0, _class, 0
 wcend:
 _class db "MAIN",0
 _title db "Teste de janela",0
 WinError db "Não foi possível criar a janela",0
 color dd 0
 BITMAPINFO    BITMAPINFOHEADER sizeof.BITMAPINFOHEADER,\  ; biSize
                                    640,\                      ; biWidth
                                    480,\                      ; biHeight
                                    1,\                        ; biPlanes       
                                    32,\                       ; biBitCount
                                    0,\                        ; biCompression  
                                    0,\                        ; biSizeImage
                                    0, \                       ; biXPelsPerMeter
                                    0, \                       ; biYPelsPerMeter
                                    0, \                       ; biClrUsed      
                                    0                          ; biClrImportant

section '.bss' data readable writeable
 wMsg MSG
 psPaint PAINTSTRUCT
 hDC dd ?
 hMemDC dd ?
 pDIBSCR dd ?
 hDIBSCR dd ?
 oDIBSCR dd ?
 hBackDC dd ?

section '.idata' import data readable writeable
 library kernel32, "KERNEL32.DLL",\
         user32, "USER32.DLL",\
         gdi32, "GDI32.DLL"

 include "api\kernel32.inc"
 include "api\user32.inc"
 include "api\gdi32.inc"

;section '.rsrc' resource data readable
    
It has a small problem: the window cut out a piece, but with time I'll straighten. My other question now is: how do I make it full screen on another resolution, like 640x480?
Post 13 Sep 2013, 21:09
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
Are you creating a game?
If so, you need the thread -- timer is not a good solution.

In order to draw in windows -- no need for the DIB section.
Just draw into memory DC for fast output:

1. CreateCompatibleDC()
2. CreateCompatibleBitmap()
3. SelectObject() from step #2 into DC from step #1
4. Draw everything on DC from step #1
5. BitBlt() from DC from step #1 into screen DC
6. Deselect all back and delete DC and bitmap

For speed you can cache DC and BMP, so you do not need to re-create each time.
Post 14 Sep 2013, 00:37
View user's profile Send private message Send e-mail Reply with quote
A$M



Joined: 29 Feb 2012
Posts: 94
A$M
AsmGuru62 wrote:
Are you creating a game?
If so, you need the thread -- timer is not a good solution.

In order to draw in windows -- no need for the DIB section.
Just draw into memory DC for fast output:

1. CreateCompatibleDC()
2. CreateCompatibleBitmap()
3. SelectObject() from step #2 into DC from step #1
4. Draw everything on DC from step #1
5. BitBlt() from DC from step #1 into screen DC
6. Deselect all back and delete DC and bitmap

For speed you can cache DC and BMP, so you do not need to re-create each time.


1. How to create a thread?
2. So how can I draw directly on the memory DC?

Ps.: Yes, I'm creating a game.
Post 14 Sep 2013, 15:39
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1180
Location: Unknown
HaHaAnonymous
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 19:56; edited 1 time in total
Post 14 Sep 2013, 16:54
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1409
Location: Toronto, Canada
AsmGuru62
The drawings in memory DC are done as usual -- using functions, like:

FillRect
FrameRect
Ellipse
MoveTo + LineTo
Polygon or something like that.

Then, when the frame is complete (in memory) -- use BitBlt() to
transfer it from memory DC to a screen DC. It works well, because
in most cases BitBlt() is accelerated by a graphics card you have.

If your game is complex, like 3D modeling - then OpenGL or DirectX maybe better to use than Win API.

I posted a simple game a while ago:
http://board.flatassembler.net/topic.php?t=15028

It has a bug however, which I never fixed.
If you hold space bar key for too long - it crashes.
Post 15 Sep 2013, 00:34
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.