REM Minimal Direct3D 11 application in BBC BASIC for Windows
      REM (C) R. T. Russell, 31-Jul-2015, http://www.bbcbasic.co.uk
      MODE 8
      REM!WC Declare constants:
      NULL                            = 0
      S_OK                            = 0
      DXGI_FORMAT_R8G8B8A8_UNORM      = 28
      DXGI_USAGE_RENDER_TARGET_OUTPUT = 1 << (1 + 4)
      D3D_DRIVER_TYPE_HARDWARE        = 1
      D3D11_SDK_VERSION               = 7
      IID_ID3D11Texture2D = FN_guid("{6f15aaf2-d208-4e89-9ab4-489535d34f9c}")
      REM Declare structures:
      DIM DXGI_RATIONAL{Numerator%, Denominator%}
      DIM DXGI_MODE_DESC{Width%, Height%, RefreshRate{} = DXGI_RATIONAL{}, \
      \                  Format%, ScanlineOrdering%, Scaling%}
      DIM DXGI_SAMPLE_DESC{Count%, Quality%}
      DIM DXGI_SWAP_CHAIN_DESC{BufferDesc{} = DXGI_MODE_DESC{}, \
      \                        SampleDesc{} = DXGI_SAMPLE_DESC{}, \
      \                        BufferUsage%, \
      \                        BufferCount%, \
      \                        OutputWindow%, \
      \                        Windowed%, \
      \                        SwapEffect%, \
      \                        Flags%}
      DIM D3D11_VIEWPORT{TopLeftX%,TopLeftY%,Width%,Height%,MinDepth%,MaxDepth%}
      REM Declare interfaces:
      DIM IDXGISwapChain{QueryInterface%,AddRef%,Release%,SetPrivateData%, \
      \ SetPrivateDataInterface%,GetPrivateData%,GetParent%,GetDevice%,Present%, \
      \ GetBuffer%,SetFullscreenState%,GetFullscreenState%,GetDesc%,ResizeBuffers%, \
      \ ResizeTarget%,GetContainingOutput%,GetFrameStatistics%,GetLastPresentCount%}
      DIM ID3D11Texture2D{QueryInterface%,AddRef%,Release%,GetDevice%, \
      \ GetPrivateData%,SetPrivateData%,SetPrivateDataInterface%,GetType%, \
      \ SetEvictionPriority%,GetEvictionPriority%,GetDesc%}
      DIM ID3D11Device{QueryInterface%,AddRef%,Release%,CreateBuffer%, \
      \ CreateTexture1D%,CreateTexture2D%,CreateTexture3D%,CreateShaderResourceView%, \
      \ CreateUnorderedAccessView%,CreateRenderTargetView%,CreateDepthStencilView%, \
      \ CreateInputLayout%,CreateVertexShader%,CreateGeometryShader%, \
      \ CreateGeometryShaderWithStreamOutput%,CreatePixelShader%,CreateHullShader%, \
      \ CreateDomainShader%,CreateComputeShader%,CreateClassLinkage%,CreateBlendState%, \
      \ CreateDepthStencilState%,CreateRasterizerState%,CreateSamplerState%, \
      \ CreateQuery%,CreatePredicate%,CreateCounter%,CreateDeferredContext%, \
      \ OpenSharedResource%,CheckFormatSupport%,CheckMultisampleQualityLevels%, \
      \ CheckCounterInfo%,CheckCounter%,CheckFeatureSupport%,GetPrivateData%, \
      \ SetPrivateData%,SetPrivateDataInterface%,GetFeatureLevel%,GetCreationFlags%, \
      \ GetDeviceRemovedReason%,GetImmediateContext%,SetExceptionMode%,GetExceptionMode%}
      DIM ID3D11DeviceContext{QueryInterface%,AddRef%,Release%,GetDevice%, \
      \ GetPrivateData%,SetPrivateData%,SetPrivateDataInterface%,VSSetConstantBuffers%, \
      \ PSSetShaderResources%,PSSetShader%,PSSetSamplers%,VSSetShader%, \
      \ DrawIndexed%,Draw%,Map%,Unmap%,PSSetConstantBuffers%,IASetInputLayout%, \
      \ IASetVertexBuffers%,IASetIndexBuffer%,DrawIndexedInstanced%,DrawInstanced%, \
      \ GSSetConstantBuffers%,GSSetShader%,IASetPrimitiveTopology%,VSSetShaderResources%, \
      \ VSSetSamplers%,Begin%,End%,GetData%,SetPredication%,GSSetShaderResources%, \
      \ GSSetSamplers%,OMSetRenderTargets%,OMSetRenderTargetsAndUnorderedAccessViews%, \
      \ OMSetBlendState%,OMSetDepthStencilState%,SOSetTargets%,DrawAuto%, \
      \ DrawIndexedInstancedIndirect%,DrawInstancedIndirect%,Dispatch%, \
      \ DispatchIndirect%,RSSetState%,RSSetViewports%,RSSetScissorRects%, \
      \ CopySubresourceRegion%,CopyResource%,UpdateSubresource%,CopyStructureCount%, \
      \ ClearRenderTargetView%,ClearUnorderedAccessViewUint%,ClearUnorderedAccessViewFloat%, \
      \ ClearDepthStencilView%,GenerateMips%,SetResourceMinLOD%,GetResourceMinLOD%, \
      \ ResolveSubresource%,ExecuteCommandList%,HSSetShaderResources%,HSSetShader%, \
      \ HSSetSamplers%,HSSetConstantBuffers%,DSSetShaderResources%,DSSetShader%, \
      \ DSSetSamplers%,DSSetConstantBuffers%,CSSetShaderResources%,CSSetUnorderedAccessViews%, \
      \ CSSetShader%,CSSetSamplers%,CSSetConstantBuffers%,VSGetConstantBuffers%, \
      \ PSGetShaderResources%,PSGetShader%,PSGetSamplers%,VSGetShader%, \
      \ PSGetConstantBuffers%,IAGetInputLayout%,IAGetVertexBuffers%,IAGetIndexBuffer%, \
      \ GSGetConstantBuffers%,GSGetShader%,IAGetPrimitiveTopology%,VSGetShaderResources%, \
      \ VSGetSamplers%,GetPredication%,GSGetShaderResources%,GSGetSamplers%, \
      \ OMGetRenderTargets%,OMGetRenderTargetsAndUnorderedAccessViews%, \
      \ OMGetBlendState%,OMGetDepthStencilState%,SOGetTargets%,RSGetState%, \
      \ RSGetViewports%,RSGetScissorRects%,HSGetShaderResources%,HSGetShader%, \
      \ HSGetSamplers%,HSGetConstantBuffers%,DSGetShaderResources%,DSGetShader%, \
      \ DSGetSamplers%,DSGetConstantBuffers%,CSGetShaderResources%,CSGetUnorderedAccessViews%, \
      \ CSGetShader%,CSGetSamplers%,CSGetConstantBuffers%,ClearState%,Flush%, \
      \ GetType%,GetContextFlags%,FinishCommandList%}
      REM: Initialise:
      SYS "LoadLibrary","D3D11.DLL" TO d3d11%
      IF d3d11% = 0 ERROR 0, "DirectX 11 is not installed"
      SYS "GetProcAddress", d3d11%, "D3D11CreateDeviceAndSwapChain" TO \
      \                             `D3D11CreateDeviceAndSwapChain`
      REM Create the swap chain:
      DIM sd{} = DXGI_SWAP_CHAIN_DESC{}
      sd.BufferCount% = 1
      sd.BufferDesc.Width% = 640
      sd.BufferDesc.Height% = 512
      sd.BufferDesc.Format% = DXGI_FORMAT_R8G8B8A8_UNORM
      sd.BufferDesc.RefreshRate.Numerator% = 60
      sd.BufferDesc.RefreshRate.Denominator% = 1
      sd.BufferUsage% = DXGI_USAGE_RENDER_TARGET_OUTPUT
      sd.OutputWindow% = @hwnd%
      sd.SampleDesc.Count% = 1
      sd.SampleDesc.Quality% = 0
      sd.Windowed% = 1
      SYS `D3D11CreateDeviceAndSwapChain`, NULL, D3D_DRIVER_TYPE_HARDWARE, \
      \   NULL, 0, NULL, 0, D3D11_SDK_VERSION, sd{}, ^pSwapChain%, \
      \   ^pd3dDevice%, NULL, ^pImmediateContext% TO result%
      IF result% <> S_OK ERROR 100, "CreateDeviceAndSwapChain failed"
      !(^IDXGISwapChain{}+4) = !pSwapChain%
      !(^ID3D11Device{}+4) = !pd3dDevice%
      !(^ID3D11DeviceContext{}+4) = !pImmediateContext%
      REM Create a render target view:
      SYS IDXGISwapChain.GetBuffer%, pSwapChain%, 0, IID_ID3D11Texture2D, \
      \   ^pBackBuffer% TO result%
      IF result% <> S_OK ERROR 100, "IDXGISwapChain::GetBuffer failed"
      !(^ID3D11Texture2D{}+4) = !pBackBuffer%
      SYS ID3D11Device.CreateRenderTargetView%, pd3dDevice%, pBackBuffer%, NULL, \
      \   ^pRenderTargetView% TO result%
      IF result% <> S_OK ERROR 100, "ID3D11Device::CreateRenderTargetView failed"
      SYS ID3D11Texture2D.Release%, pBackBuffer%
      SYS ID3D11DeviceContext.OMSetRenderTargets%, pImmediateContext%, \
      \   1, ^pRenderTargetView%, NULL
      DIM vp{} = D3D11_VIEWPORT{} : REM All members are floats
      vp.Width% = FN_f4(sd.BufferDesc.Width%)
      vp.Height% = FN_f4(sd.BufferDesc.Height%)
      vp.MinDepth% = 0
      vp.MaxDepth% = FN_f4(1.0)
      vp.TopLeftX% = 0
      vp.TopLeftY% = 0
      SYS ID3D11DeviceContext.RSSetViewports%, pImmediateContext%, 1, vp{}
      REM Render:
      DIM ClearColor%(3)
      ClearColor%() = 0, FN_f4(0.125), FN_f4(0.6), FN_f4(1.0) : REM RGBA
      SYS ID3D11DeviceContext.ClearRenderTargetView%, pImmediateContext%, \
      \   pRenderTargetView%, ^ClearColor%(0)
      SYS IDXGISwapChain.Present%, pSwapChain%, 0, 0
      END
      DEF FN_f4(a#)
      LOCAL A% : PRIVATE F%
      IF F% = 0 THEN
        SYS "LoadLibrary", "OLEAUT32.DLL" TO F%
        SYS "GetProcAddress", F%, "VarR4FromR8" TO F%
      ENDIF
      a# *= 1.0#
      SYS F%,!^a#,!(^a#+4),^A%
      =A%
      DEF FN_guid(a$)
      LOCAL C%, M% : PRIVATE O%
      DIM C% 30, M% LOCAL 2*LENa$+2
      C% = (C%+15) AND -16 : M% = (M%+1) AND -2
      IF O% = 0 THEN
        SYS "LoadLibrary", "OLE32.DLL" TO O%
        SYS "GetProcAddress", O%, "CLSIDFromString" TO O%
      ENDIF
      SYS "MultiByteToWideChar", 0, 0, a$, -1, M%, LENa$+1
      SYS O%, M%, C%
      = C% 
           REM ****************************************************************
      REM
      REM Create a DirectX11 Device
      REM
      REM ****************************************************************
      DEF PROC_Init_D3D11(hwnd%)
      INSTALL @lib$ + "DirectX11\Functions\DLL"
      INSTALL @lib$ + "DirectX11\Functions\Helper"
      CALL @lib$ + "DirectX11\Constants"
      CALL @lib$ + "DirectX11\Structures"
      CALL @lib$ + "DirectX11\Interfaces"
      PROC_Helper_AssembleFNf
      REM Get the Dlls and the functions we need
      D3D11DLL%                       = FN_DLL_LoadDLL("D3D11.DLL")
      D3D11CreateDeviceAndSwapChain%  = FN_DLL_GetFunctionAddress(D3D11DLL%, "D3D11CreateDeviceAndSwapChain")
      D3DX11DLL%                      = FN_DLL_LoadDLL(FN_GetD3DX11DLL)
      D3DX11CompileFromFile%          = FN_DLL_GetFunctionAddress(D3DX11DLL%, "D3DX11CompileFromFileA")
      REM Create our swap chain description{}
      LOCAL scd{}
      DIM scd{} = DXGI_SWAP_CHAIN_DESC{}
      REM Fill out its members
      scd.BufferCount%       = 1
      scd.BufferDesc.Width%  = SCREENWIDTH
      scd.BufferDesc.Height% = SCREENHEIGHT
      scd.BufferDesc.Format% = DXGI_R8G8B8A8_UNORM
      scd.BufferDesc.RefreshRate.Numerator% = 60
      scd.BufferDesc.RefreshRate.Denominator% = 1
      scd.BufferUsage% = DXGI_USAGE_RENDER_TARGET_OUTPUT
      scd.OutputWindow% = hwnd%
      scd.SampleDesc.Count% = 4
      scd.SampleDesc.Quality% = 0
      scd.Windowed% = _TRUE
      scd.Flags% = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
      REM Create the device
      SYS D3D11CreateDeviceAndSwapChain%, 0,               \
      \                                   D3D_DRIVER_TYPE_HARDWARE,  \
      \                                   0,               \
      \                                   0,               \
      \                                   0,               \
      \                                   0,               \
      \                                   D3D11_SDK_VERSION ,             \
      \                                   scd{},            \
      \                                   ^SwapChain%, \
      \                                   ^Device%,   \
      \                                   0,                 \
      \                                   ^DeviceContext%       TO R%
      IF R% PROC_D3DERR(R%) ELSE IF V% PRINT"Device Created."
      PROC_Helper_CreateInterface(IDevice{}, ID3D11Device{}, Device%)
      PROC_Helper_CreateInterface(ISwapChain{}, IDXGISwapChain{}, SwapChain%)
      PROC_Helper_CreateInterface(IDeviceContext{}, ID3D11DeviceContext{}, DeviceContext%)
      REM Get the address of the back buffer
      SYS ISwapChain.GetBuffer%, SwapChain%, 0, IID_ID3D11Texture2D{}, ^pBackBuffer% TO R%
      IF R% THEN ERROR 100,"Error : swapchain->GetBuffer : "+STR$~R%
      REM Use the BackBufferAddress to create the Render Target
      SYS IDevice.CreateRenderTargetView%, Device%, pBackBuffer%, 0, ^BackBuffer% TO R%
      IF R% THEN ERROR 100,"Error : Couldn't Use the BackBufferAddress to create the Render Target"
      REM Release the BackBuffer pointer
      SYS !(!pBackBuffer% + 8), pBackBuffer%
      REM OMSetRenderTargets : Returns Void
      SYS IDeviceContext.OMSetRenderTargets%, DeviceContext%, 1, ^BackBuffer%, 0
      REM Set the viewport
      DIM vp{} = D3D11_VIEWPORT{}
      vp.Width%    = FNf(SCREENWIDTH)
      vp.Height%   = FNf(SCREENHEIGHT)
      vp.TopLeftX% = 0
      vp.TopLeftY% = 0
      SYS IDeviceContext.RSSetViewports%, DeviceContext%, 1, vp{}
      ENDPROC
      REM ****************************************************************
      REM
      REM Closes DirextX11 and releases all the Objects created
      REM
      REM ****************************************************************
      DEF PROC_Close_D3D11(D%)
      PRINT'
      REM switch to windowed mode
      SwapChain% += 0
      IF SwapChain% THEN
        SYS ISwapChain.SetFullscreenState%, SwapChain%, 0, 0
      ENDIF
      REM Release Roger!
      REM Release all our objects
      IF FN_Helper_Release(VertexShader%)  = 0 IF V% PRINT"VertexShader released."
      IF FN_Helper_Release(PixelShader%)   = 0 IF V% PRINT"PixelShader released."
      IF FN_Helper_Release(BackBuffer%)    = 0 IF V% PRINT"BackBuffer released."
      IF FN_Helper_Release(SwapChain%)     = 0 IF V% PRINT"Swapchain released."
      IF FN_Helper_Release(Device%)        = 0 IF V% PRINT"Device released."
      IF FN_Helper_Release(DeviceContext%) = 0 IF V% PRINT"DeviceContext released."
      REM Release our dlls
      IF FN_DLL_FreeDLL(D3D11DLL%) IF V% THEN PRINT"D3D11.DLL Freed."
      IF FN_DLL_FreeDLL(D3DX11DLL%) IF V% THEN PRINT"D3DX11.DLL Freed."
      ENDPROC
      DEF FN_Helper_Release(RETURN O%)
      LOCAL R%
      O% += 0 : IF O% THEN SYS !(!O%+8), O% TO R%
      =R%
      REM ****************************************************************
      REM
      REM DirextX11 Error handling
      REM
      REM ****************************************************************
      DEF PROC_D3DERR(E%)
      D3DERR_INVALIDCALL           =          FN_MAKE_D3DHRESULT(2156)
      D3DERR_WASSTILLDRAWING       =          FN_MAKE_D3DHRESULT(540)
      ENDPROC
      DEF FN_MAKE_D3DHRESULT(C%)
      =FN_MAKE_HRESULT(1, &876, C%)
      DEF FN_MAKE_D3D10_HRESULT(C%)
      =FN_MAKE_HRESULT(1, &879, C%)
      DEF FN_MAKE_D3D11_HRESULT(C%)
      =FN_MAKE_HRESULT(1, &87C, C%)
      DEF FN_MAKE_HRESULT(S%, F%, C%)
      =(S%<<31) OR (F%<<16) OR C%