;
; Startup and OpenGL setup code.
;
; Coded by:
;	s_tec
;

%include "win32n.inc"
%include "nasmgl.inc"
%include "link.inc"

		global	_main

		extern	@demo_init@0
		extern	@demo_render@8
		extern	@music@0
		extern	_wave_handle

;-----------------------------------------------------------------------------
; Constants:
;-----------------------------------------------------------------------------

		;Demo constants:
k_main_x	equ	800			;Demo width
k_main_y	equ	600			;Demo height
k_main_length	equ	20*1000			;Demo run time, in ms

;-----------------------------------------------------------------------------
; Unitialized data:
;-----------------------------------------------------------------------------
		section .bss

;-----------------------------------------------------------------------------
; Initialized data:
;-----------------------------------------------------------------------------
		section	.data
%ifdef FULLSCREEN
s_main_mode:		;Display mode:
.dmDeviceName		times	CCHDEVICENAME db 0
.dmSpecVersion		dw	0
.dmDriverVersion	dw	0
.dmSize			dw	DEVMODE_size
.dmDriverExtra		dw	0
.dmFields		dd	DM_PELSWIDTH|DM_PELSHEIGHT
.dmOrientation		dw	0
.dmPaperSize		dw	0
.dmPaperiLength		dw	0
.dmPaperWidth		dw	0
.dmScale		dw	0
.dmCopies		dw	0
.dmDefaultSource	dw	0
.dmPrintQuality		dw	0
.dmColor		dw	0
.dmDuplex		dw	0
.dmYResolution		dw	0
.dmTTOption		dw	0
.dmCollate		dw	0
.dmFormName		times	32 db 0
.dmLogPixels		dw	0
.dmBitsPerPel		dd	0
.dmPelsWidth		dd	k_main_x
.dmPelsHeight		dd	k_main_y
.dmDisplayFlags		dd	0
.dmDisplayFrequency	dd	0
.dmDisplayOrientation	dd	0
%endif

			;The main window's class:
s_main_class:		db	'static', 0
			align	4, db 0

s_main_format:		;Pixel format (40 bytes):
.nSize:			dw	0
.nVersion:		dw	0
.dwFlags:		dd	PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER
.iPixelType:		db	0
.cColorBits:		db	0
.cRedBits:		db	0
.cRedShift:		db	0
.cGreenBits:		db	0
.cGreenShift:		db	0
.cBlueBits:		db	0
.cBlueShift:		db	0
.cAlphaBits:		db	0
.cAlphaShift:		db	0
.cAccumBits:		db	0
.cAccumRedBits:		db	0
.cAccumGreenBits:	db	0
.cAccumBlueBits:	db	0
.cAccumAlphaBits:	db	0
.cDepthBits:		db	16
.cStencilBits:		db	0
.cAuxBuffers:		db	0
.iLayerType:		db	0
.bReserved:		db	0
.dwLayerMask:		dd	0
.dwVisibleMask:		dd	0
.dwDamageMask:		dd	0

s_main_time:		;Current time information:
.wType:			dd	TIME_SAMPLES
.sample:		dd	0
.padding:		dd	0

;-----------------------------------------------------------------------------
; _main
; Program entry point
;-----------------------------------------------------------------------------
		section	.text
_main:
%ifdef FULLSCREEN
		;Go to fullscreen mode:
		push	CDS_FULLSCREEN		;dwflags
		push	s_main_mode		;lpDevMode
		call	ChangeDisplaySettings

		;Create the window:
		push	0			;lpParam
		push	0			;hInstance
		push	0			;hMenu
		push	0			;hWndParent
		push	0			;nHeight
		push	0			;nWidth
		push	0			;y
		push	0			;x
		push	WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_MAXIMIZE ;dwStyle
		push	0			;lpWindowName
		push	s_main_class		;lpClassName
		push	0			;dwExStyle
		call	CreateWindowEx
%else
		;Create the window:
		push	0			;lpParam
		push	0			;hInstance
		push	0			;hMenu
		push	0			;hWndParent
		push	k_main_y		;nHeight
		push	k_main_x		;nWidth
		push	0			;y
		push	100			;x
		push	WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS ;dwStyle
		push	0			;lpWindowName
		push	s_main_class		;lpClassName
		push	0			;dwExStyle
		call	CreateWindowEx
%endif
		;Get the device context:
		push	eax
		call	GetDC
		mov	esi, eax

		;Set up the pixel format:
		push	s_main_format		;ppfd
		push	esi			;hdc
		call	ChoosePixelFormat
		push	s_main_format		;ppfd
		push	eax			;iPixelFormat
		push	esi			;hdc
		call	SetPixelFormat

		;Set up the rendering context:
		push	esi			;hdc
		call	wglCreateContext
		push	eax			;hglrc
		push	esi			;hdc
		call	wglMakeCurrent

		;Hide the mouse:
		push	0
		call	ShowCursor

		;Prepare the demo:
		call	@demo_init@0
		call	@music@0

		;Find the current time:
		xor	edi, edi
.repeat:	push	MMTIME_size		;cbmmt
		push	s_main_time		;pmmt
		push	dword[_wave_handle]	;hwo
		call	waveOutGetPosition

		;Calculate time (ecx = t + dt, edx = dt, edi = t):
		mov	ecx, [s_main_time.sample]
		mov	edx, ecx
		sub	edx, edi
		mov	edi, ecx
		add	ecx, edx
		
		;Render the demo:
		call	@demo_render@8
		test	eax, eax
		jz	.quit

		;Copy to the display:
		push	esi			;hdc
		call	SwapBuffers

		;while (!GetAsyncKeyState(VK_ESCAPE))
		push	VK_ESCAPE
		call	GetAsyncKeyState
		test	eax, eax
		jz	.repeat

		;Clean up and exit:
.quit:		push	0			;uExitCode 
		call	ExitProcess
