
#include once "windows.bi"
#include once "win/d3d9.bi"
#include once "crt.bi"

dim shared as HWND              g_hWnd       = NULL
dim shared as LPDIRECT3D9       g_pD3D       = NULL
dim shared as LPDIRECT3DDEVICE9 g_pd3dDevice = NULL
dim shared as integer WinWid,Winhei

function WindowProc(hWnd as HWND,msg as UINT,wParam as WPARAM,lParam as LPARAM ) as LRESULT  
  select case ( msg )
  case WM_CREATE
    dim as Rect RC,RW,RD
    GetClientRect(hwnd,@RC)
    GetWindowRect(hwnd,@RW)
    GetWindowRect(GetDesktopWindow(),@RD)
    RW.right -= RW.left
    RW.bottom -= RW.top
    var SX = (RW.right-RC.right)+WinWid
    var SY = (RW.bottom-RC.bottom)+WinHei
    var PX = (((RD.right-RD.left)-SX)/2)+RD.left
    var PY = (((RD.bottom-RD.top)-SY)/2)+RD.top
    SetWindowPos(hwnd,null,PX,PY,SX,SY,SWP_NOZORDER)    
  case WM_KEYDOWN
    select case( wParam )
    case VK_ESCAPE
      PostQuitMessage(0)
      'g_bRenderInWireFrame = not g_bRenderInWireFrame
      'if( g_bRenderInWireFrame ) then
      '    IDirect3DDevice9_SetRenderState(g_pd3dDevice, D3DRS_FILLMODE, D3DFILL_WIREFRAME )
      'else
      '    IDirect3DDevice9_SetRenderState(g_pd3dDevice, D3DRS_FILLMODE, D3DFILL_SOLID )
      'end if
    end select
    
  case WM_CLOSE
    PostQuitMessage(0)	
		
  case WM_DESTROY
    PostQuitMessage(0)
    
  case else
    return DefWindowProc( hWnd, msg, wParam, lParam )
  end select
  
	return 0
end function
function WinMain(hInstance as HINSTANCE,hPrevInstance as HINSTANCE,lpCmdLine as string,nCmdShow as integer) as integer
  
	dim as WNDCLASSEX winClass 
	dim as MSG        uMsg
  
	with winClass
		.lpszClassName = @"MY_WINDOWS_CLASS"
		.cbSize        = len(WNDCLASSEX)
		.style         = CS_HREDRAW or CS_VREDRAW
		.lpfnWndProc   = @WindowProc
		.hInstance     = hInstance
		.hIcon	       = LoadIcon(hInstance, cast(LPCTSTR,IDI_APPLICATION))
    .hIconSm	   = LoadIcon(hInstance, cast(LPCTSTR,IDI_APPLICATION))
		.hCursor       = LoadCursor(NULL, IDC_ARROW)
		.hbrBackground = cast(HBRUSH,GetStockObject(BLACK_BRUSH))
		.lpszMenuName  = NULL
		.cbClsExtra    = 0
		.cbWndExtra    = 0
  end with
  
	if( RegisterClassEx( @winClass ) = FALSE ) then
		return E_FAIL
  end if
  
	g_hWnd = CreateWindowEx( NULL, "MY_WINDOWS_CLASS", _
  "Direct3D (DX9) - Primitive Types", _
  WS_OVERLAPPEDWINDOW or WS_VISIBLE, _
  CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL )
  
	if( g_hWnd = NULL ) then
		return E_FAIL
  end if
  
  ShowWindow( g_hWnd, nCmdShow )
  UpdateWindow( g_hWnd )
  
end function
function d3d_flip() as integer
  static as msg uMsg = type(0,-1,-1,-1)
  if uMsg.message = WM_QUIT then return 0
  while PeekMessage( @uMsg, NULL, 0, 0, PM_REMOVE )
    TranslateMessage( @uMsg )
    DispatchMessage( @uMsg )
    if uMsg.message = WM_QUIT then      
      UnregisterClass( "MY_WINDOWS_CLASS", GetModuleHandle( null ) )
      return 0
    end if      
  wend
  IDirect3DDevice9_Present(g_pd3dDevice, NULL, NULL, NULL, NULL )
  return 1
end function

dim shared as LPDIRECT3DVERTEXBUFFER9 g_pTriangleFan_VB   = NULL

#define D3DFVF_MY_VERTEX ( D3DFVF_XYZRHW or D3DFVF_DIFFUSE or D3DFVF_SPECULAR )
type Vertex
	as single x, y, z, w '' Position of vertex in 3D space
  as DWORD cDiffuse   '' Color of vertex
  as DWORD cSpecular  '' Color of vertex
end type

dim shared as Vertex g_triangleFan(0 to 8191) => { _
( 320,  0, 0, 1, &hFF0000FF, &hFFFFFFFF ),_
(   0,  0, 0, 1, &hFF00FF00, &hFFFFFFFF ),_
( 0.5,  0, 0, 1, &hFFFF0000, &hFFFFFFFF ),_
( 320,480, 0, 1, &hFF00FFFF, &hFFFFFFFF ),_
( 480,240, 0, 1, &hFFFFFF00, &hFFFFFFFF ),_
( 640,  0, 0, 1, &hFFFF00FF, &hFFFFFFFF ) }

sub init( iWid as integer , iHei as integer)
  
  const VertMax = 8192
  
  WinWid = iWid:WinHei=iHei
  WinMain( GetModuleHandle( null ), null, command( ), SW_NORMAL )
  g_pD3D = Direct3DCreate9( D3D_SDK_VERSION )
  
  dim as D3DDISPLAYMODE d3ddm  
  IDirect3D9_GetAdapterDisplayMode( g_pD3D, D3DADAPTER_DEFAULT, @d3ddm )
  
  dim as D3DPRESENT_PARAMETERS d3dpp    
  d3dpp.Windowed               = true
  d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD
  d3dpp.BackBufferFormat       = d3ddm.Format
  d3dpp.EnableAutoDepthStencil = true
  d3dpp.AutoDepthStencilFormat = D3DFMT_D16
  d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE
  
  IDirect3D9_CreateDevice( g_pD3D, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, _
  D3DCREATE_HARDWARE_VERTEXPROCESSING, _
  @d3dpp, @g_pd3dDevice )
  
	IDirect3DDevice9_SetRenderState(g_pd3dDevice,D3DRS_LIGHTING, FALSE)
	IDirect3DDevice9_SetRenderState(g_pd3dDevice,D3DRS_CULLMODE, D3DCULL_NONE)
	
	dim as Vertex ptr pVertices = NULL
  
	''
	'' Point List
	''
	IDirect3DDevice9_CreateVertexBuffer(g_pd3dDevice, VertMax*sizeof(Vertex), 0, _
  D3DFVF_MY_VERTEX,D3DPOOL_DEFAULT, @g_pTriangleFan_VB,NULL )
	
end sub
sub shutDown( )
	if( g_pTriangleFan_VB <> NULL ) then
    IDirect3DVertexBuffer9_Release(g_pTriangleFan_VB) 
  end if
  
  if( g_pd3dDevice <> NULL ) then
    IDirect3DDevice9_Release(g_pd3dDevice)
  end if
  
  if( g_pD3D <> NULL ) then
    IDirect3D9_Release( g_pD3D )
  end if
end sub
sub render( iTriCount as integer )
  
  dim as Vertex ptr pVertices = NULL
	IDirect3DVertexBuffer9_Lock( g_pTriangleFan_VB, 0, Sizeof(g_triangleFan)*6, cast( any ptr ptr, @pVertices ), 0 )
  memcpy( pVertices, @g_triangleFan(0), sizeof(g_triangleFan)*6 )
  IDirect3DVertexBuffer9_Unlock(g_pTriangleFan_VB)
  
  IDirect3DDevice9_Clear( g_pd3dDevice, 0, NULL, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, _
  D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0 )
	
	IDirect3DDevice9_BeginScene(g_pd3dDevice)		
  IDirect3DDevice9_SetStreamSource(g_pd3dDevice, 0, g_pTriangleFan_VB, 0, len(Vertex) )
  IDirect3DDevice9_SetFVF(g_pd3dDevice, D3DFVF_MY_VERTEX )
  IDirect3DDevice9_DrawPrimitive(g_pd3dDevice, D3DPT_TRIANGLEFAN, 0 , iTriCount-1 )
	
	IDirect3DDevice9_EndScene(g_pd3dDevice)  
  
end sub

Init(640,480)

do
  render(6)
  if d3d_flip()=0 then exit do
  sleep 1,1
loop

ShutDown()
