News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

EndPaint placement

Started by dc, June 09, 2017, 06:26:39 AM

Previous topic - Next topic

qWord

The rectangle passed to InvalidRect is not initialized. Also, never send WM_PAINT yourself - it's an message intended to be send by windows components to your code and not vice versa. You might also remove the UpdateWindow call and let window decided when to redraw.

BTW: you can pass a Null pointer to InvalidateRect to invalidate the whole client area
BTW2: forcing the background to be erased makes no sense for you application, because you draw the entire client area yourself
MREAL macros - when you need floating point arithmetic while assembling!

dc

so this doesn't initialize the rectangle?

    .if uMsg==WM_CREATE
        mov tangle.top, 0
        mov tangle.left, 0
        mov tangle.right, 500
        mov tangle.bottom, 500

hutch--

OK,

I have put the line,

        invoke EndPaint, hWnd, addr ps

at the end of the WM_PAINT where it should be, manually set the main window so it was not clipping the edges of your display and it shows a 10 x 10 set of zero images in the client area.
I commented out the line,

            ; dxd sFlag

as I could not see what it was useful for.

You have the mouse cursor set to a "+" symbol but there is no code written for acting on mouse movements or mouse click events so I don't know what you are trying to do.

qWord

Quote from: dc on June 12, 2017, 07:24:08 AM
so this doesn't initialize the rectangle?
tangle is a local variable and thus created on the stack each time the WndProc is called. Put the definition in the .data?-section to make it static.
MREAL macros - when you need floating point arithmetic while assembling!

hutch--

This may be useful in the WM_LBUTTONUP processing.


  ; at the top
    LOCAL hiwd  :DWORD
    LOCAL lowd  :DWORD


    .elseif uMsg==WM_LBUTTONUP
;         invoke InvalidateRect, hWnd, addr tangle, TRUE
;         invoke UpdateWindow, hWnd
;         invoke SendMessage, hWnd, WM_PAINT, 0, 0

        mov eax, lParam
        movzx ecx, ax
        mov lowd, ecx
        rol eax, 16
        movzx ecx, ax
        mov hiwd, ecx

        invoke SetWindowText,hWnd,str$(hiwd)

dc

no fixes yet, im trying to flip bitmaps in the main window
ive been able to with the endpaint function in the wrong place but it makes a bad memory leak

qWord

Here a working version of your game.asm with some simple extensions:
.386
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE
Include Game.inc
WinMain Proc  hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
    mov wc.cbSize, SizeOf WNDCLASSEX
    mov wc.style, CS_HREDRAW or CS_VREDRAW
    mov wc.lpfnWndProc, Offset WndProc
    mov wc.cbClsExtra,NULL
    mov wc.cbWndExtra,NULL
    push hInst
    POP wc.hInstance
    mov wc.hbrBackground, COLOR_MENU
    mov wc.lpszMenuName, NULL
    mov wc.lpszClassName, Offset ClassName
    invoke LoadIcon, hInstance, offset IDI_ICON
    mov wc.hIcon,EAX
    mov wc.hIconSm,0
    Invoke LoadCursor, NULL, IDC_CROSS
    mov wc.hCursor,EAX
    Invoke RegisterClassEx, addr wc
    Invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, addr ClassName, addr szAppName,\
                        WS_SYSMENU, 400, 200, 500, 500, NULL, NULL, hInst, NULL
    mov hwnd, eax
    Invoke ShowWindow, hwnd, SW_SHOWNORMAL
    Invoke UpdateWindow, hwnd
    .while TRUE
        Invoke GetMessage, addr msg, NULL, 0, 0
    .break .If (!eax)
        Invoke TranslateMessage, addr msg
        Invoke DispatchMessage, addr msg
    .endw
    mov eax, msg.wParam
    ret
WinMain endp
WndProc Proc uses esi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT,wndrect:RECT

    .data?
       
        squares BYTE 10*10 dup (?)
       
    .code

    .if uMsg==WM_CREATE
       
        ;
        ; resize window to get 500x500 client area
        ;
        invoke GetWindowRect,hWnd,addr wndrect
        invoke GetClientRect,hWnd,addr rect
        mov ecx,500
        mov edx,ecx
        add ecx,rect.left
        add edx,rect.top
        sub ecx,rect.right
        sub edx,rect.bottom
        sub ecx,wndrect.left
        sub edx,wndrect.top
        add ecx,wndrect.right
        add edx,wndrect.bottom
        invoke SetWindowPos,hWnd, NULL,0,0,ecx,edx,SWP_NOMOVE or SWP_NOZORDER
       
        invoke LoadBitmap,hInstance,IDB_1
        mov hBmp1,eax
        invoke LoadBitmap,hInstance,IDB_0
        mov hBmp0,eax
       
    .elseIf uMsg==WM_PAINT
        invoke BeginPaint, hWnd, addr ps
        mov hdc, eax
        invoke CreateCompatibleDC, hdc
        mov hdcCH, eax
        invoke CreateCompatibleDC, hdc
        mov hdcP, eax
        invoke CreateCompatibleBitmap, hdc, 500, 500
        mov hBmpP, eax
        invoke SelectObject, hdcP, hBmpP
        mov oldP, eax

        ; esi = index in array 'squares'
        xor esi,esi
        mov oldCH, esi
        mov sX, esi
        mov sY, esi
       
        ; for each row
        .while sY<500
           
            ; for each column in current row
            .while sX<500
               
                ; select bitmap for current square
                .if squares[esi]
                    invoke SelectObject, hdcCH, hBmp1
                .else
                    invoke SelectObject, hdcCH, hBmp0
                .endif
               
                ; save handle of default bitmap for first selection only
                .if !oldCH
                    mov oldCH,eax
                .endif
                               
                invoke BitBlt, hdcP, sX, sY, 50, 50, hdcCH, 0, 0, SRCCOPY
               
                ; next column
                add sX, 50
               
                ; update index
                add esi,1
            .endw
           
            ; next row
            add sY, 50
           
            ; reset to column 0
            mov sX, 0
        .endw
       
        invoke BitBlt, hdc, 0, 0, 500, 500, hdcP, 0, 0, SRCCOPY
       
        invoke SelectObject, hdcCH, oldCH
        invoke DeleteDC, hdcCH
        invoke SelectObject, hdcP, oldP
        invoke DeleteDC, hdcP
        invoke DeleteObject, hBmpP
       
        invoke EndPaint, hWnd, addr ps
       
    .elseif uMsg==WM_LBUTTONUP
       
        ; get x-coord.
        xor edx,edx
        movsx eax,WORD ptr lParam
        mov ecx,50
        idiv ecx
        push eax
       
        ; get y-coord.
        xor edx,edx
        movsx eax,WORD ptr lParam[2]
        idiv ecx
       
        ; index = x + y * 10
        pop edx
        imul eax,eax,10
        add eax,edx
       
        ; if index valid
        .if eax < LENGTHOF squares
           
            ; toggle state
            xor squares[eax],1
           
            ; force redraw of client area
            invoke InvalidateRect, hWnd, 0,FALSE
        .endif
       
    .elseif uMsg==WM_DESTROY
        invoke DeleteObject,hBmp0
        invoke DeleteObject,hBmp1
       
        invoke PostQuitMessage,NULL
    .else
        Invoke DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .endif
    xor eax, eax
    ret
WndProc EndP

End Start

MREAL macros - when you need floating point arithmetic while assembling!

dc

right on, i still dont see what is making the difference but ill find it, thanx, sure seems like it would be more strait forward.
i probly just got a wrong variable somewhere or something :)

qWord

Quote from: dc on June 12, 2017, 11:52:01 AM
right on, i still dont see what is making the difference
The important difference is the InvalidatRect-call and the removed SendMessage(WM_PAINT). Applying this changes to your previously uploaded code make it work.
MREAL macros - when you need floating point arithmetic while assembling!

dc

sweet success, thanx everyone, ill post the finished project when its done, dont hold your breath, as i am a working man with grand kids :)

dc

so far what i have... wondering how much figuring out should be the game and splainin i should do up front

dc

this version is a bit closer to what i had in mind

jj2007

You ran out of mojo??  ::)

It looks very impressing, but how does it work?

dc

i am seeing it needs quite a bit of explaining, also im noticing that people dont really care much for it, thinkin of moving on, make crystal clusters by changing the maze into little diamond patterns, direct the spark to pass by one to make it green and you get mojo, turn all 4 green to explode the cluster which changes the maze slightly, then secondary explosions from new clusters created by the explosions explode, 3 or more secondary ones result in the spark going quantum leaving behind residual sparks which are worth more mojo and points, if you cross the threshold amount of mojo, the speed increases and all the clusters explode and change the maze.... when the spark is trapped in a small loop, you lose mojo quickly - the smaller the loop the faster you lose mojo....

jj2007

Quote from: dc on October 06, 2017, 08:21:20 AM
i am seeing it needs quite a bit of explaining
yes

Quotemake crystal clusters by changing the maze into little diamond patterns, direct the spark
how? special key?