hInstance = $400000

include 'win32wx.inc'
DIB_RGB_COLORS EQU 0

ORDER = 8
MAX_X = 1 shl (ORDER+1) - 1
MAX_Y = MAX_X

;##########################################################################
macro Hilbert {
	DIRECTION equ edx
	COLOR = $00FF00 ; green

	pushad
	mov edi,[pvBits]
	push RULE_L
	mov esi,esp
	mov ecx,ORDER
	mov DIRECTION,0
	mov dword [edi],COLOR
	call Do_Rule
	pop esi
	popad
}


RULE_L dd \
	Right,\
	Do_Rule,RULE_R,\
	Forward,\
	Left,\
	Do_Rule,RULE_L,\
	Forward,\
	Do_Rule,RULE_L,\
	Left,\
	Forward,\
	Do_Rule,RULE_R,\
	Right,\
	0
RULE_R dd \
	Left,\
	Do_Rule,RULE_L,\
	Forward,\
	Right,\
	Do_Rule,RULE_R,\
	Forward,\
	Do_Rule,RULE_R,\
	Right,\
	Forward,\
	Do_Rule,RULE_L,\
	Left,\
	0
;##########################################################################



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

Hilbert

	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

;##########################################################################





;########################################

Do_Rule:
	dec ecx
	lodsd
	js .x
	push esi
	mov esi,eax

	lodsd
  .0:	call eax
  .1:	lodsd
	test eax,eax
	jne .0

	pop esi
  .x:	inc ecx
	retn

; built-in rules
Right:	inc DIRECTION
	retn

Left:	dec DIRECTION
	retn

Forward:
	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