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 0xdead
;
;	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

	mov [BitmapInfo.biSize], 40 ;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], 0
	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

	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] 

	HWND_TOP equ 0 
	SWP_NOOWNERZORDER equ 0x0200
	SWP_FRAMECHANGED equ 0x0020

	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


