hInstance = $400000

include 'win32wx.inc'
DIB_RGB_COLORS EQU 0

ORDER = 8
MAX_X = 1 shl (ORDER+1) - 1
MAX_Y = MAX_X
COLOR = $00FF00 ; green



class WNDCLASSEX sizeof.WNDCLASSEX,0,win_proc,0,0,hInstance,0,0,0,0,CLASSNAME,0
CLASSNAME TCHAR "HilbertW",0

bmi32 BITMAPINFOHEADER sizeof.BITMAPINFOHEADER,\
      MAX_X,MAX_Y,1,32,BI_RGB,4*MAX_X*MAX_Y,0,0,0,0



START:	xor ebp,ebp
	invoke CreateCompatibleDC,ebp
	mov [hDCBitmap],eax
	invoke CreateDIBSection,[hDCBitmap],bmi32,DIB_RGB_COLORS,pvBits,0,0
	mov [hBitmap], eax
	invoke SelectObject,[hDCBitmap],eax

	invoke LoadCursorA,ebp,32649
	mov [class.hCursor],eax
	invoke RegisterClassEx,class


STYLE  = WS_VISIBLE or WS_CAPTION or WS_SYSMENU
STYLEX = WS_EX_APPWINDOW or WS_EX_TOOLWINDOW or WS_EX_WINDOWEDGE
	push ebp
	push hInstance
	push ebp
	push ebp
	push MAX_Y
	push MAX_X
	push ebp
	push ebp

	mov eax,esp
	invoke AdjustWindowRectEx,eax,STYLE,FALSE,STYLEX

	pop eax
	pop edx
	sub [esp],eax
	sub [esp+4],edx
	push CW_USEDEFAULT
	push CW_USEDEFAULT
	push STYLE
	push CLASSNAME
	push CLASSNAME
	push STYLEX
	call [CreateWindowEx]
	mov esi,eax


; draw on DIB
mov edi,[pvBits]
;add edi,4 * (4*MAX_X + 1)
mov eax,00b
mov edx,1
mov ecx,ORDER
call Hilbert


	xor ebp,ebp
	invoke InvalidateRgn,esi,ebp,TRUE
	mov ebx,msg
	jmp .get
.mloop: push ebx
	push ebx
	call [TranslateMessage]
	call [DispatchMessage]
.get:	invoke GetMessage,ebx,ebp,ebp,ebp
	test eax,eax
	jne .mloop

	invoke DeleteObject,[hBitmap]
	invoke DeleteDC,[hDCBitmap]

	invoke ExitProcess,ebp
	retn


;##########################################################################

win_proc:
	label .hWnd   dword at esp+4*1
	label .uMsg   dword at esp+4*2
	label .wParam dword at esp+4*3
	label .lParam dword at esp+4*4

	cmp [.uMsg],WM_DESTROY
	je .xit
	cmp [.uMsg],WM_ERASEBKGND
	je .bkgnd
	jmp [DefWindowProc]
.bkgnd: invoke BeginPaint,[.hWnd+4],ps
	invoke BitBlt,[.wParam+32],0,0,MAX_X,MAX_Y,[hDCBitmap],0,0,SRCCOPY
	invoke EndPaint,[.hWnd+4],ps
	lahf
	retn 16
.xit:	invoke PostQuitMessage,0
	retn 16

;##########################################################################


; Hilbert curve
Hilbert:
    .order equ ecx
    .direction equ eax
    ; 00 right
    ; 01 up
    ; 10 left
    ; 11 down
    .rotation equ edx
    ; 1 clockwise
    ;-1 counterclockwise
    mov dword[edi],COLOR
.recursion:
    dec .order
    js .exit

    call .corner

    call .corner

    call .recursion

    sub .direction,.rotation
    call .step

    neg .rotation
    call .recursion

    ; preserve original values
    sub .direction,.rotation
    neg .rotation
.exit:
    inc .order
    retn

.corner:
    neg .rotation
    sub .direction,.rotation
    call .recursion
.step:
    ror .direction,2
    sbb ebx,ebx 	; dir&&2 ? -1 : 0

    rol .direction,2
    sbb ebp,ebp 	; dir&&1 ? -1 : 0

    and ebp,MAX_X-1	; dir&&1 ? MAX_X-1 : 0
    inc ebp		; dir&&1 ? MAX_X : 1

    xor ebp,ebx 	; conditional negate
    sub ebp,ebx 	; based on dir&&2

    mov dword[edi+ebp*4],COLOR
    lea edi,[edi+ebp*4]
    mov dword[edi+ebp*4],COLOR
    lea edi,[edi+ebp*4]
    retn


msg MSG

ps PAINTSTRUCT

hDCBitmap dd ?
hBitmap dd ?
pvBits dd ?


.end START