Browse files

merged dx8 & dx9 versions

  • Loading branch information...
1 parent dee17f3 commit 771818ecd29fb8617bf62553ed61dbfc5feedde1 kv committed Sep 24, 2011
Showing with 2,449 additions and 11,176 deletions.
  1. +1 −0 .gitignore
  2. +6 −6 CMakeLists.txt
  3. +1 −0 HGE_CMake_Issues.txt
  4. +2 −2 include/hge.h
  5. +42 −0 include/hge_gapi.h
  6. +1 −0 readme.txt
  7. 0 src/{core_directx9 → core}/BASS/bass.h
  8. +7 −1 src/{core_directx8 → core}/CMakeLists.txt
  9. 0 src/{core_directx9 → core}/demo.cpp
  10. +1,116 −0 src/core/graphics.cpp
  11. +345 −0 src/core/hge_impl.h
  12. 0 src/{core_directx9 → core}/ini.cpp
  13. 0 src/{core_directx9 → core}/input.cpp
  14. 0 src/{core_directx9 → core}/power.cpp
  15. 0 src/{core_directx9 → core}/random.cpp
  16. 0 src/{core_directx9 → core}/resource.cpp
  17. 0 src/{core_directx9 → core}/sound.cpp
  18. +891 −0 src/core/system.cpp
  19. 0 src/{core_directx9 → core}/timer.cpp
  20. BIN src/core_directx8.zip
  21. +0 −845 src/core_directx8/BASS/bass.h
  22. +0 −3 src/core_directx8/bcc_implib.bat
  23. +0 −216 src/core_directx8/demo.cpp
  24. +0 −980 src/core_directx8/graphics.cpp
  25. +0 −345 src/core_directx8/hge_impl.h
  26. +0 −73 src/core_directx8/ini.cpp
  27. +0 −252 src/core_directx8/input.cpp
  28. +0 −53 src/core_directx8/power.cpp
  29. +0 −32 src/core_directx8/random.cpp
  30. +0 −259 src/core_directx8/resource.cpp
  31. +0 −562 src/core_directx8/sound.cpp
  32. +0 −865 src/core_directx8/system.cpp
  33. +0 −28 src/core_directx8/timer.cpp
  34. BIN src/core_directx9.zip
  35. +0 −67 src/core_directx9/CMakeLists.txt
  36. +0 −985 src/core_directx9/graphics.cpp
  37. +0 −345 src/core_directx9/hge_impl.h
  38. +0 −866 src/core_directx9/system.cpp
  39. +3 −2 src/fontconv/CMakeLists.txt
  40. +7 −1 src/fonted/CMakeLists.txt
  41. 0 src/{helpers_directx9 → helpers}/CMakeLists.txt
  42. 0 src/{helpers_directx9 → helpers}/hgeanim.cpp
  43. 0 src/{helpers_directx9 → helpers}/hgecolor.cpp
  44. 0 src/{helpers_directx9 → helpers}/hgedistort.cpp
  45. 0 src/{helpers_directx9 → helpers}/hgefont.cpp
  46. 0 src/{helpers_directx9 → helpers}/hgegui.cpp
  47. 0 src/{helpers_directx9 → helpers}/hgeguictrls.cpp
  48. 0 src/{helpers_directx9 → helpers}/hgeparticle.cpp
  49. 0 src/{helpers_directx9 → helpers}/hgepmanager.cpp
  50. 0 src/{helpers_directx9 → helpers}/hgerect.cpp
  51. 0 src/{helpers_directx9 → helpers}/hgeresource.cpp
  52. 0 src/{helpers_directx9 → helpers}/hgesprite.cpp
  53. 0 src/{helpers_directx9 → helpers}/hgestrings.cpp
  54. 0 src/{helpers_directx9 → helpers}/hgevector.cpp
  55. 0 src/{helpers_directx9 → helpers}/parser.cpp
  56. 0 src/{helpers_directx9 → helpers}/parser.h
  57. 0 src/{helpers_directx9 → helpers}/resources.cpp
  58. 0 src/{helpers_directx9 → helpers}/resources.h
  59. BIN src/helpers_directx8.zip
  60. +0 −42 src/helpers_directx8/CMakeLists.txt
  61. +0 −165 src/helpers_directx8/hgeanim.cpp
  62. +0 −82 src/helpers_directx8/hgecolor.cpp
  63. +0 −242 src/helpers_directx8/hgedistort.cpp
  64. +0 −333 src/helpers_directx8/hgefont.cpp
  65. +0 −397 src/helpers_directx8/hgegui.cpp
  66. +0 −357 src/helpers_directx8/hgeguictrls.cpp
  67. +0 −262 src/helpers_directx8/hgeparticle.cpp
  68. +0 −91 src/helpers_directx8/hgepmanager.cpp
  69. +0 −45 src/helpers_directx8/hgerect.cpp
  70. +0 −304 src/helpers_directx8/hgeresource.cpp
  71. +0 −302 src/helpers_directx8/hgesprite.cpp
  72. +0 −168 src/helpers_directx8/hgestrings.cpp
  73. +0 −69 src/helpers_directx8/hgevector.cpp
  74. +0 −209 src/helpers_directx8/parser.cpp
  75. +0 −77 src/helpers_directx8/parser.h
  76. +0 −1,045 src/helpers_directx8/resources.cpp
  77. +0 −184 src/helpers_directx8/resources.h
  78. BIN src/helpers_directx9.zip
  79. +7 −1 src/particleed/CMakeLists.txt
  80. +7 −1 src/pngopt/CMakeLists.txt
  81. +9 −1 src/texasm/CMakeLists.txt
  82. +4 −3 src/zlib-1.2.5/contrib/minizip/ioapi.c
  83. BIN tools/fonted/fontconv.exe
  84. BIN tools/fonted/fonted.exe
  85. +0 −8 tools/fonted/fonted.ini
  86. BIN tools/particleed/particleed.exe
  87. BIN tools/textools/pngopt.exe
  88. BIN tools/textools/texasm.exe
  89. BIN tutorials/precompiled/hge.dll
  90. BIN tutorials/precompiled/hge_tut01.exe
  91. BIN tutorials/precompiled/hge_tut02.exe
  92. BIN tutorials/precompiled/hge_tut03.exe
  93. BIN tutorials/precompiled/hge_tut04.exe
  94. BIN tutorials/precompiled/hge_tut05.exe
  95. BIN tutorials/precompiled/hge_tut06.exe
  96. BIN tutorials/precompiled/hge_tut07.exe
  97. BIN tutorials/precompiled/hge_tut08.exe
View
1 .gitignore
@@ -1,3 +1,4 @@
.build-*/
bin/
linklib/
+*.log
View
12 CMakeLists.txt
@@ -8,8 +8,8 @@ cmake_minimum_required( VERSION 2.8 )
##----------------------------------------
SET( DIRECTX_SDK_DIR "C:/DXSDK" )
-SET( HGE_DIRECTX_VER "8" )
-## SET( HGE_DIRECTX_VER "9" )
+##--- set this to 8 or 9 ---
+SET( HGE_DIRECTX_VER "9" )
##----------------------------------------
## End of manual configuration section
@@ -19,9 +19,9 @@ SET( HGE_DIRECTX_VER "8" )
-
+add_definitions( "-DHGE_DIRECTX_VER=${HGE_DIRECTX_VER}" )
# disable warnings on STD non conformance and security issues
-add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WIN32_WINNT=0x0501 /MP )
+add_definitions( "-D_CRT_SECURE_NO_WARNINGS" "-D_CRT_NONSTDC_NO_WARNINGS" "-D_SCL_SECURE_NO_WARNINGS" "-D_WIN32_WINNT=0x0501" "/MP" )
## add_definitions( /MDd )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${HGE_SOURCE_DIR}/bin CACHE PATH "Single Directory for all executables." )
@@ -35,8 +35,8 @@ add_subdirectory( src/zlib-1.2.5 )
add_subdirectory( src/libPNG )
#--- HGE core library and helpers ---
-add_subdirectory( src/helpers_directx${HGE_DIRECTX_VER} )
-add_subdirectory( src/core_directx${HGE_DIRECTX_VER} )
+add_subdirectory( src/helpers )
+add_subdirectory( src/core )
#--- HGE TOOLS - comment out of not needed ---
add_subdirectory( src/fontconv )
View
1 HGE_CMake_Issues.txt
@@ -1,3 +1,4 @@
+https://github.com/kvakvs/hge
POSSIBLE ISSUES LIST
-Added "/NODEFAULTLIB:libci" option for MSVC, because D3D8.LIB refers to this library but
View
4 include/hge.h
@@ -5,14 +5,13 @@
**
** System layer API
*/
-
-
#ifndef HGE_H
#define HGE_H
#include <windows.h>
+
#define HGE_VERSION 0x180
// CMake adds PROJECTNAME_EXPORTS when compiles DLL
@@ -69,6 +68,7 @@ typedef unsigned char BYTE;
/*
** HGE Handle types
*/
+// FIXME: Won't compile in 64-bit mode due to handles (4 bytes) holding a pointer (8 bytes)
typedef DWORD HTEXTURE;
typedef DWORD HTARGET;
typedef DWORD HEFFECT;
View
42 include/hge_gapi.h
@@ -0,0 +1,42 @@
+//-------------------------------------------------
+// Modifications and additional types, included internally, do not include from your game project
+// GAPI dependent includes and defines (DX8/DX9 switch)
+// added by kvakvs@yandex.ru
+// Forum discussion thread http://relishgames.com/forum/viewtopic.php?t=6235
+// GIT repository https://github.com/kvakvs/hge
+//-------------------------------------------------
+
+#if HGE_DIRECTX_VER == 8
+ #include <d3d8.h>
+ #include <d3dx8.h>
+#else
+ #if HGE_DIRECTX_VER == 9
+ #include <d3d9.h>
+ #include <d3dx9.h>
+ #else
+ #error Please change your C++ preprocessor defs settings or edit HGE.H and define HGE_DIRECTX_VER to be 8 or 9
+ #endif
+#endif
+
+#if HGE_DIRECTX_VER == 8
+ typedef IDirect3D8 hgeGAPI;
+ typedef IDirect3DDevice8 hgeGAPIDevice;
+ typedef IDirect3DVertexBuffer8 hgeGAPIVertexBuffer;
+ typedef IDirect3DIndexBuffer8 hgeGAPIIndexBuffer;
+ typedef IDirect3DTexture8 hgeGAPITexture;
+ typedef IDirect3DSurface8 hgeGAPISurface;
+ typedef D3DVIEWPORT8 hgeGAPIViewport;
+ typedef D3DADAPTER_IDENTIFIER8 hgeGAPIAdapterIdentifier;
+#endif
+
+#if HGE_DIRECTX_VER == 9
+ typedef IDirect3D9 hgeGAPI;
+ typedef IDirect3DDevice9 hgeGAPIDevice;
+ typedef IDirect3DVertexBuffer9 hgeGAPIVertexBuffer;
+ typedef IDirect3DIndexBuffer9 hgeGAPIIndexBuffer;
+ typedef IDirect3DTexture9 hgeGAPITexture;
+ typedef IDirect3DSurface9 hgeGAPISurface;
+ typedef D3DVIEWPORT9 hgeGAPIViewport;
+ typedef D3DADAPTER_IDENTIFIER9 hgeGAPIAdapterIdentifier;
+#endif
+
View
1 readme.txt
@@ -1,6 +1,7 @@
This is README for HGE library source reconfigured with CMake
For original readme file refer to Original_README.txt
=============================================================
+https://github.com/kvakvs/hge
INSTALLING
----------
View
0 src/core_directx9/BASS/bass.h → src/core/BASS/bass.h
File renamed without changes.
View
8 src/core_directx8/CMakeLists.txt → src/core/CMakeLists.txt
@@ -42,7 +42,13 @@ include_directories( ${DIRECTX_SDK_DIR}/include )
#------ link directories listed ------
link_directories( ${HGE_SOURCE_DIR}/linklib )
link_directories( ${DIRECTX_SDK_DIR}/lib ${DIRECTX_SDK_DIR}/lib/x64 ${DIRECTX_SDK_DIR}/lib/x86 )
-link_libraries( d3d8 d3dx8 winmm )
+if( ${HGE_DIRECTX_VER} MATCHES "8" )
+ link_libraries( d3d8 d3dx8 )
+endif()
+if( ${HGE_DIRECTX_VER} MATCHES "9" )
+ link_libraries( d3d9 d3dx9 )
+endif()
+link_libraries( winmm )
link_libraries( zlib hgehelpers )
#------ precompiled headers support (not done for now) ------
View
0 src/core_directx9/demo.cpp → src/core/demo.cpp
File renamed without changes.
View
1,116 src/core/graphics.cpp
@@ -0,0 +1,1116 @@
+/*
+** Haaf's Game Engine 1.8
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Core functions implementation: graphics
+*/
+
+
+#include "hge_impl.h"
+// GAPI dependent includes and defines (DX8/DX9 switch) by kvakvs@yandex.ru
+#include "hge_gapi.h"
+
+
+void CALL HGE_Impl::Gfx_Clear(DWORD color)
+{
+ if(pCurTarget)
+ {
+ if(pCurTarget->pDepth)
+ pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
+ else
+ pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
+ }
+ else
+ {
+ if(bZBuffer)
+ pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 1.0f, 0 );
+ else
+ pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, color, 1.0f, 0 );
+ }
+}
+
+void CALL HGE_Impl::Gfx_SetClipping(int x, int y, int w, int h)
+{
+ hgeGAPIViewport vp;
+ int scr_width, scr_height;
+
+ if(!pCurTarget) {
+ scr_width=pHGE->System_GetStateInt(HGE_SCREENWIDTH);
+ scr_height=pHGE->System_GetStateInt(HGE_SCREENHEIGHT);
+ }
+ else {
+ scr_width=Texture_GetWidth((HTEXTURE)pCurTarget->pTex);
+ scr_height=Texture_GetHeight((HTEXTURE)pCurTarget->pTex);
+ }
+
+ if(!w) {
+ vp.X=0;
+ vp.Y=0;
+ vp.Width=scr_width;
+ vp.Height=scr_height;
+ }
+ else
+ {
+ if(x<0) { w+=x; x=0; }
+ if(y<0) { h+=y; y=0; }
+
+ if(x+w > scr_width) w=scr_width-x;
+ if(y+h > scr_height) h=scr_height-y;
+
+ vp.X=x;
+ vp.Y=y;
+ vp.Width=w;
+ vp.Height=h;
+ }
+
+ vp.MinZ=0.0f;
+ vp.MaxZ=1.0f;
+
+ _render_batch();
+ pD3DDevice->SetViewport(&vp);
+
+ D3DXMATRIX tmp;
+ D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
+ D3DXMatrixTranslation(&tmp, -0.5f, +0.5f, 0.0f);
+ D3DXMatrixMultiply(&matProj, &matProj, &tmp);
+ D3DXMatrixOrthoOffCenterLH(&tmp, (float)vp.X, (float)(vp.X+vp.Width), -((float)(vp.Y+vp.Height)), -((float)vp.Y), vp.MinZ, vp.MaxZ);
+ D3DXMatrixMultiply(&matProj, &matProj, &tmp);
+ pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
+}
+
+void CALL HGE_Impl::Gfx_SetTransform(float x, float y, float dx, float dy, float rot, float hscale, float vscale)
+{
+ D3DXMATRIX tmp;
+
+ if(vscale==0.0f) D3DXMatrixIdentity(&matView);
+ else
+ {
+ D3DXMatrixTranslation(&matView, -x, -y, 0.0f);
+ D3DXMatrixScaling(&tmp, hscale, vscale, 1.0f);
+ D3DXMatrixMultiply(&matView, &matView, &tmp);
+ D3DXMatrixRotationZ(&tmp, -rot);
+ D3DXMatrixMultiply(&matView, &matView, &tmp);
+ D3DXMatrixTranslation(&tmp, x+dx, y+dy, 0.0f);
+ D3DXMatrixMultiply(&matView, &matView, &tmp);
+ }
+
+ _render_batch();
+ pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
+}
+
+bool CALL HGE_Impl::Gfx_BeginScene(HTARGET targ)
+{
+ hgeGAPISurface * pSurf = 0, * pDepth = 0;
+
+ D3DDISPLAYMODE Mode;
+ CRenderTargetList *target=(CRenderTargetList *)targ;
+
+ HRESULT hr = pD3DDevice->TestCooperativeLevel();
+ if (hr == D3DERR_DEVICELOST) return false;
+ else if (hr == D3DERR_DEVICENOTRESET)
+ {
+ if(bWindowed)
+ {
+ if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN)
+ {
+ _PostError("Can't determine desktop video mode");
+ return false;
+ }
+
+ d3dppW.BackBufferFormat = Mode.Format;
+ if(_format_id(Mode.Format) < 4) nScreenBPP=16;
+ else nScreenBPP=32;
+ }
+
+ if(!_GfxRestore()) return false;
+ }
+
+ if(VertArray)
+ {
+ _PostError("Gfx_BeginScene: Scene is already being rendered");
+ return false;
+ }
+
+ if(target != pCurTarget)
+ {
+ if(target)
+ {
+ target->pTex->GetSurfaceLevel(0, &pSurf);
+ pDepth=target->pDepth;
+ }
+ else
+ {
+ pSurf=pScreenSurf;
+ pDepth=pScreenDepth;
+ }
+#if HGE_DIRECTX_VER == 8
+ if(FAILED(pD3DDevice->SetRenderTarget(pSurf, pDepth)))
+#endif
+#if HGE_DIRECTX_VER == 9
+ if(FAILED(pD3DDevice->SetRenderTarget(0, pSurf)))
+#endif
+ {
+ if(target) pSurf->Release();
+ _PostError("Gfx_BeginScene: Can't set render target");
+ return false;
+ }
+ if(target)
+ {
+ pSurf->Release();
+ if(target->pDepth) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
+ else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
+ _SetProjectionMatrix(target->width, target->height);
+ }
+ else
+ {
+ if(bZBuffer) pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
+ else pD3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_FALSE );
+ _SetProjectionMatrix(nScreenWidth, nScreenHeight);
+ }
+
+ pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
+ D3DXMatrixIdentity(&matView);
+ pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
+
+ pCurTarget=target;
+ }
+
+ pD3DDevice->BeginScene();
+#if HGE_DIRECTX_VER == 8
+ pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );
+#endif
+#if HGE_DIRECTX_VER == 9
+ pVB->Lock( 0, 0, (VOID**)&VertArray, 0 );
+#endif
+ return true;
+}
+
+void CALL HGE_Impl::Gfx_EndScene()
+{
+ _render_batch(true);
+ pD3DDevice->EndScene();
+ if(!pCurTarget) pD3DDevice->Present( NULL, NULL, NULL, NULL );
+}
+
+void CALL HGE_Impl::Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color, float z)
+{
+ if(VertArray)
+ {
+ if(CurPrimType!=HGEPRIM_LINES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_LINES || CurTexture || CurBlendMode!=BLEND_DEFAULT)
+ {
+ _render_batch();
+
+ CurPrimType=HGEPRIM_LINES;
+ if(CurBlendMode != BLEND_DEFAULT) _SetBlendMode(BLEND_DEFAULT);
+ if(CurTexture) { pD3DDevice->SetTexture(0, 0); CurTexture=0; }
+ }
+
+ int i=nPrim*HGEPRIM_LINES;
+ VertArray[i].x = x1; VertArray[i+1].x = x2;
+ VertArray[i].y = y1; VertArray[i+1].y = y2;
+ VertArray[i].z = VertArray[i+1].z = z;
+ VertArray[i].col = VertArray[i+1].col = color;
+ VertArray[i].tx = VertArray[i+1].tx =
+ VertArray[i].ty = VertArray[i+1].ty = 0.0f;
+
+ nPrim++;
+ }
+}
+
+void CALL HGE_Impl::Gfx_RenderTriple(const hgeTriple *triple)
+{
+ if(VertArray)
+ {
+ if(CurPrimType!=HGEPRIM_TRIPLES || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_TRIPLES || CurTexture!=triple->tex || CurBlendMode!=triple->blend)
+ {
+ _render_batch();
+
+ CurPrimType=HGEPRIM_TRIPLES;
+ if(CurBlendMode != triple->blend) _SetBlendMode(triple->blend);
+ if(triple->tex != CurTexture) {
+ pD3DDevice->SetTexture( 0, (hgeGAPITexture *)triple->tex );
+ CurTexture = triple->tex;
+ }
+ }
+
+ memcpy(&VertArray[nPrim*HGEPRIM_TRIPLES], triple->v, sizeof(hgeVertex)*HGEPRIM_TRIPLES);
+ nPrim++;
+ }
+}
+
+void CALL HGE_Impl::Gfx_RenderQuad(const hgeQuad *quad)
+{
+ if(VertArray)
+ {
+ if(CurPrimType!=HGEPRIM_QUADS || nPrim>=VERTEX_BUFFER_SIZE/HGEPRIM_QUADS || CurTexture!=quad->tex || CurBlendMode!=quad->blend)
+ {
+ _render_batch();
+
+ CurPrimType=HGEPRIM_QUADS;
+ if(CurBlendMode != quad->blend) _SetBlendMode(quad->blend);
+ if(quad->tex != CurTexture)
+ {
+ pD3DDevice->SetTexture( 0, (hgeGAPITexture *)quad->tex );
+ CurTexture = quad->tex;
+ }
+ }
+
+ memcpy(&VertArray[nPrim*HGEPRIM_QUADS], quad->v, sizeof(hgeVertex)*HGEPRIM_QUADS);
+ nPrim++;
+ }
+}
+
+hgeVertex* CALL HGE_Impl::Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim)
+{
+ if(VertArray)
+ {
+ _render_batch();
+
+ CurPrimType=prim_type;
+ if(CurBlendMode != blend) _SetBlendMode(blend);
+ if(tex != CurTexture)
+ {
+ pD3DDevice->SetTexture( 0, (hgeGAPITexture *)tex );
+ CurTexture = tex;
+ }
+
+ *max_prim=VERTEX_BUFFER_SIZE / prim_type;
+ return VertArray;
+ }
+ else return 0;
+}
+
+void CALL HGE_Impl::Gfx_FinishBatch(int nprim)
+{
+ nPrim=nprim;
+}
+
+HTARGET CALL HGE_Impl::Target_Create(int width, int height, bool zbuffer)
+{
+ CRenderTargetList *pTarget;
+ D3DSURFACE_DESC TDesc;
+
+ pTarget = new CRenderTargetList;
+ pTarget->pTex=0;
+ pTarget->pDepth=0;
+
+ if(FAILED(D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET,
+ d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &pTarget->pTex)))
+ {
+ _PostError("Can't create render target texture");
+ delete pTarget;
+ return 0;
+ }
+
+ pTarget->pTex->GetLevelDesc(0, &TDesc);
+ pTarget->width=TDesc.Width;
+ pTarget->height=TDesc.Height;
+
+ if(zbuffer)
+ {
+#if HGE_DIRECTX_VER == 8
+ if(FAILED(pD3DDevice->CreateDepthStencilSurface(pTarget->width, pTarget->height,
+ D3DFMT_D16, D3DMULTISAMPLE_NONE, &pTarget->pDepth)))
+#endif
+#if HGE_DIRECTX_VER == 9
+ if(FAILED(pD3DDevice->CreateDepthStencilSurface(width, height,
+ D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, false, &pTarget->pDepth, NULL)))
+#endif
+ {
+ pTarget->pTex->Release();
+ _PostError("Can't create render target depth buffer");
+ delete pTarget;
+ return 0;
+ }
+ }
+
+ pTarget->next=pTargets;
+ pTargets=pTarget;
+
+ return (HTARGET)pTarget;
+}
+
+void CALL HGE_Impl::Target_Free(HTARGET target)
+{
+ CRenderTargetList *pTarget=pTargets, *pPrevTarget=NULL;
+
+ while(pTarget)
+ {
+ if((CRenderTargetList *)target == pTarget)
+ {
+ if(pPrevTarget)
+ pPrevTarget->next = pTarget->next;
+ else
+ pTargets = pTarget->next;
+
+ if(pTarget->pTex) pTarget->pTex->Release();
+ if(pTarget->pDepth) pTarget->pDepth->Release();
+
+ delete pTarget;
+ return;
+ }
+
+ pPrevTarget = pTarget;
+ pTarget = pTarget->next;
+ }
+}
+
+HTEXTURE CALL HGE_Impl::Target_GetTexture(HTARGET target)
+{
+ CRenderTargetList *targ=(CRenderTargetList *)target;
+ if(target) return (HTEXTURE)targ->pTex;
+ else return 0;
+}
+
+HTEXTURE CALL HGE_Impl::Texture_Create(int width, int height)
+{
+ hgeGAPITexture * pTex;
+
+ if( FAILED( D3DXCreateTexture( pD3DDevice, width, height,
+ 1, // Mip levels
+ 0, // Usage
+ D3DFMT_A8R8G8B8, // Format
+ D3DPOOL_MANAGED, // Memory pool
+ &pTex ) ) )
+ {
+ _PostError("Can't create texture");
+ return NULL;
+ }
+
+ return (HTEXTURE)pTex;
+}
+
+HTEXTURE CALL HGE_Impl::Texture_Load(const char *filename, DWORD size, bool bMipmap)
+{
+ void *data;
+ DWORD _size;
+ D3DFORMAT fmt1, fmt2;
+ hgeGAPITexture * pTex;
+ D3DXIMAGE_INFO info;
+ CTextureList *texItem;
+
+ if(size) { data=(void *)filename; _size=size; }
+ else
+ {
+ data=pHGE->Resource_Load(filename, &_size);
+ if(!data) return NULL;
+ }
+
+ if(*(DWORD*)data == 0x20534444) // Compressed DDS format magic number
+ {
+ fmt1=D3DFMT_UNKNOWN;
+ fmt2=D3DFMT_A8R8G8B8;
+ }
+ else
+ {
+ fmt1=D3DFMT_A8R8G8B8;
+ fmt2=D3DFMT_UNKNOWN;
+ }
+
+// if( FAILED( D3DXCreateTextureFromFileInMemory( pD3DDevice, data, _size, &pTex ) ) ) pTex=NULL;
+ if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
+ D3DX_DEFAULT, D3DX_DEFAULT,
+ bMipmap ? 0:1, // Mip levels
+ 0, // Usage
+ fmt1, // Format
+ D3DPOOL_MANAGED, // Memory pool
+ D3DX_FILTER_NONE, // Filter
+ D3DX_DEFAULT, // Mip filter
+ 0, // Color key
+ &info, NULL,
+ &pTex ) ) )
+
+ if( FAILED( D3DXCreateTextureFromFileInMemoryEx( pD3DDevice, data, _size,
+ D3DX_DEFAULT, D3DX_DEFAULT,
+ bMipmap ? 0:1, // Mip levels
+ 0, // Usage
+ fmt2, // Format
+ D3DPOOL_MANAGED, // Memory pool
+ D3DX_FILTER_NONE, // Filter
+ D3DX_DEFAULT, // Mip filter
+ 0, // Color key
+ &info, NULL,
+ &pTex ) ) )
+
+ {
+ _PostError("Can't create texture");
+ if(!size) Resource_Free(data);
+ return NULL;
+ }
+
+ if(!size) Resource_Free(data);
+
+ texItem=new CTextureList;
+ texItem->tex=(HTEXTURE)pTex;
+ texItem->width=info.Width;
+ texItem->height=info.Height;
+ texItem->next=textures;
+ textures=texItem;
+
+ return (HTEXTURE)pTex;
+}
+
+void CALL HGE_Impl::Texture_Free(HTEXTURE tex)
+{
+ hgeGAPITexture * pTex = (hgeGAPITexture *)tex;
+ CTextureList *texItem=textures, *texPrev=0;
+
+ while(texItem)
+ {
+ if(texItem->tex==tex)
+ {
+ if(texPrev) texPrev->next=texItem->next;
+ else textures=texItem->next;
+ delete texItem;
+ break;
+ }
+ texPrev=texItem;
+ texItem=texItem->next;
+ }
+ if(pTex != NULL) pTex->Release();
+}
+
+int CALL HGE_Impl::Texture_GetWidth(HTEXTURE tex, bool bOriginal)
+{
+ D3DSURFACE_DESC TDesc;
+ hgeGAPITexture * pTex = (hgeGAPITexture *)tex;
+ CTextureList *texItem=textures;
+
+ if(bOriginal)
+ {
+ while(texItem)
+ {
+ if(texItem->tex==tex) return texItem->width;
+ texItem=texItem->next;
+ }
+ return 0;
+ }
+ else
+ {
+ if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0;
+ else return TDesc.Width;
+ }
+}
+
+
+int CALL HGE_Impl::Texture_GetHeight(HTEXTURE tex, bool bOriginal)
+{
+ D3DSURFACE_DESC TDesc;
+ hgeGAPITexture * pTex = (hgeGAPITexture *)tex;
+ CTextureList *texItem=textures;
+
+ if(bOriginal)
+ {
+ while(texItem)
+ {
+ if(texItem->tex==tex) return texItem->height;
+ texItem=texItem->next;
+ }
+ return 0;
+ }
+ else
+ {
+ if(FAILED(pTex->GetLevelDesc(0, &TDesc))) return 0;
+ else return TDesc.Height;
+ }
+}
+
+
+DWORD * CALL HGE_Impl::Texture_Lock(HTEXTURE tex, bool bReadOnly, int left, int top, int width, int height)
+{
+ hgeGAPITexture * pTex = (hgeGAPITexture *)tex;
+ D3DSURFACE_DESC TDesc;
+ D3DLOCKED_RECT TRect;
+ RECT region, *prec;
+ int flags;
+
+ pTex->GetLevelDesc(0, &TDesc);
+ if(TDesc.Format!=D3DFMT_A8R8G8B8 && TDesc.Format!=D3DFMT_X8R8G8B8) return 0;
+
+ if(width && height)
+ {
+ region.left=left;
+ region.top=top;
+ region.right=left+width;
+ region.bottom=top+height;
+ prec=&region;
+ }
+ else prec=0;
+
+ if(bReadOnly) flags=D3DLOCK_READONLY;
+ else flags=0;
+
+ if(FAILED(pTex->LockRect(0, &TRect, prec, flags)))
+ {
+ _PostError("Can't lock texture");
+ return 0;
+ }
+
+ return (DWORD *)TRect.pBits;
+}
+
+
+void CALL HGE_Impl::Texture_Unlock(HTEXTURE tex)
+{
+ hgeGAPITexture * pTex = (hgeGAPITexture *)tex;
+ pTex->UnlockRect(0);
+}
+
+//////// Implementation ////////
+
+void HGE_Impl::_render_batch(bool bEndScene)
+{
+ if(VertArray)
+ {
+ pVB->Unlock();
+
+ if(nPrim)
+ {
+ switch(CurPrimType)
+ {
+ case HGEPRIM_QUADS:
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, nPrim<<2, 0, nPrim<<1);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, nPrim<<2, 0, nPrim<<1);
+#endif
+ break;
+
+ case HGEPRIM_TRIPLES:
+ pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, nPrim);
+ break;
+
+ case HGEPRIM_LINES:
+ pD3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, nPrim);
+ break;
+ }
+
+ nPrim=0;
+ }
+
+ if(bEndScene) VertArray = 0;
+#if HGE_DIRECTX_VER == 8
+ else pVB->Lock( 0, 0, (BYTE**)&VertArray, 0 );
+#endif
+#if HGE_DIRECTX_VER == 9
+ else pVB->Lock( 0, 0, (VOID**)&VertArray, 0 );
+#endif
+ }
+}
+
+void HGE_Impl::_SetBlendMode(int blend)
+{
+ if((blend & BLEND_ALPHABLEND) != (CurBlendMode & BLEND_ALPHABLEND))
+ {
+ if(blend & BLEND_ALPHABLEND) pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
+ else pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ }
+
+ if((blend & BLEND_ZWRITE) != (CurBlendMode & BLEND_ZWRITE))
+ {
+ if(blend & BLEND_ZWRITE) pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ else pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ }
+
+ if((blend & BLEND_COLORADD) != (CurBlendMode & BLEND_COLORADD))
+ {
+ if(blend & BLEND_COLORADD) pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);
+ else pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ }
+
+ CurBlendMode = blend;
+}
+
+void HGE_Impl::_SetProjectionMatrix(int width, int height)
+{
+ D3DXMATRIX tmp;
+ D3DXMatrixScaling(&matProj, 1.0f, -1.0f, 1.0f);
+ D3DXMatrixTranslation(&tmp, -0.5f, height+0.5f, 0.0f);
+ D3DXMatrixMultiply(&matProj, &matProj, &tmp);
+ D3DXMatrixOrthoOffCenterLH(&tmp, 0, (float)width, 0, (float)height, 0.0f, 1.0f);
+ D3DXMatrixMultiply(&matProj, &matProj, &tmp);
+}
+
+bool HGE_Impl::_GfxInit()
+{
+ static const char *szFormats[]={"UNKNOWN", "R5G6B5", "X1R5G5B5", "A1R5G5B5", "X8R8G8B8", "A8R8G8B8"};
+ hgeGAPIAdapterIdentifier AdID;
+ D3DDISPLAYMODE Mode;
+ D3DFORMAT Format=D3DFMT_UNKNOWN;
+ UINT nModes, i;
+
+// Init D3D
+#if HGE_DIRECTX_VER == 8
+ pD3D=Direct3DCreate8(120); // D3D_SDK_VERSION
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3D=Direct3DCreate9(D3D_SDK_VERSION); // D3D_SDK_VERSION
+#endif
+ if(pD3D==NULL)
+ {
+ _PostError("Can't create D3D interface");
+ return false;
+ }
+
+// Get adapter info
+
+#if HGE_DIRECTX_VER == 8
+ pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &AdID);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &AdID);
+#endif
+ System_Log("D3D Driver: %s",AdID.Driver);
+ System_Log("Description: %s",AdID.Description);
+ System_Log("Version: %d.%d.%d.%d",
+ HIWORD(AdID.DriverVersion.HighPart),
+ LOWORD(AdID.DriverVersion.HighPart),
+ HIWORD(AdID.DriverVersion.LowPart),
+ LOWORD(AdID.DriverVersion.LowPart));
+
+// Set up Windowed presentation parameters
+
+ if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &Mode)) || Mode.Format==D3DFMT_UNKNOWN)
+ {
+ _PostError("Can't determine desktop video mode");
+ if(bWindowed) return false;
+ }
+
+ ZeroMemory(&d3dppW, sizeof(d3dppW));
+
+ d3dppW.BackBufferWidth = nScreenWidth;
+ d3dppW.BackBufferHeight = nScreenHeight;
+ d3dppW.BackBufferFormat = Mode.Format;
+ d3dppW.BackBufferCount = 1;
+ d3dppW.MultiSampleType = D3DMULTISAMPLE_NONE;
+ d3dppW.hDeviceWindow = hwnd;
+ d3dppW.Windowed = TRUE;
+
+#if HGE_DIRECTX_VER == 8
+ if(nHGEFPS==HGEFPS_VSYNC) d3dppW.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
+ else d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
+#endif
+#if HGE_DIRECTX_VER == 9
+ if(nHGEFPS==HGEFPS_VSYNC) {
+ d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
+ d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+ } else {
+ d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
+ d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+ }
+#endif
+
+ if(bZBuffer)
+ {
+ d3dppW.EnableAutoDepthStencil = TRUE;
+ d3dppW.AutoDepthStencilFormat = D3DFMT_D16;
+ }
+
+// Set up Full Screen presentation parameters
+
+#if HGE_DIRECTX_VER == 8
+ nModes=pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT);
+#endif
+#if HGE_DIRECTX_VER == 9
+ nModes=pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, Mode.Format);
+#endif
+
+ for(i=0; i<nModes; i++)
+ {
+#if HGE_DIRECTX_VER == 8
+ pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, i, &Mode);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, Mode.Format, i, &Mode);
+#endif
+
+ if(Mode.Width != (UINT)nScreenWidth || Mode.Height != (UINT)nScreenHeight) continue;
+ if(nScreenBPP==16 && (_format_id(Mode.Format) > _format_id(D3DFMT_A1R5G5B5))) continue;
+ if(_format_id(Mode.Format) > _format_id(Format)) Format=Mode.Format;
+ }
+
+ if(Format == D3DFMT_UNKNOWN)
+ {
+ _PostError("Can't find appropriate full screen video mode");
+ if(!bWindowed) return false;
+ }
+
+ ZeroMemory(&d3dppFS, sizeof(d3dppFS));
+
+ d3dppFS.BackBufferWidth = nScreenWidth;
+ d3dppFS.BackBufferHeight = nScreenHeight;
+ d3dppFS.BackBufferFormat = Format;
+ d3dppFS.BackBufferCount = 1;
+ d3dppFS.MultiSampleType = D3DMULTISAMPLE_NONE;
+ d3dppFS.hDeviceWindow = hwnd;
+ d3dppFS.Windowed = FALSE;
+
+ d3dppFS.SwapEffect = D3DSWAPEFFECT_FLIP;
+ d3dppFS.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
+
+#if HGE_DIRECTX_VER == 8
+ if(nHGEFPS==HGEFPS_VSYNC) d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+ else d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+#endif
+#if HGE_DIRECTX_VER == 9
+ if(nHGEFPS==HGEFPS_VSYNC) d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+ else d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+#endif
+ if(bZBuffer)
+ {
+ d3dppFS.EnableAutoDepthStencil = TRUE;
+ d3dppFS.AutoDepthStencilFormat = D3DFMT_D16;
+ }
+
+ d3dpp = bWindowed ? &d3dppW : &d3dppFS;
+
+ if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
+ else nScreenBPP=32;
+
+// Create D3D Device
+
+ if( FAILED( pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+ d3dpp, &pD3DDevice ) ) )
+ {
+ _PostError("Can't create D3D device");
+ return false;
+ }
+
+ _AdjustWindow();
+
+ System_Log("Mode: %d x %d x %s\n",nScreenWidth,nScreenHeight,szFormats[_format_id(Format)]);
+
+// Create vertex batch buffer
+
+ VertArray=0;
+ textures=0;
+
+// Init all stuff that can be lost
+
+ _SetProjectionMatrix(nScreenWidth, nScreenHeight);
+ D3DXMatrixIdentity(&matView);
+
+ if(!_init_lost()) return false;
+
+ Gfx_Clear(0);
+
+ return true;
+}
+
+int HGE_Impl::_format_id(D3DFORMAT fmt)
+{
+ switch(fmt) {
+ case D3DFMT_R5G6B5: return 1;
+ case D3DFMT_X1R5G5B5: return 2;
+ case D3DFMT_A1R5G5B5: return 3;
+ case D3DFMT_X8R8G8B8: return 4;
+ case D3DFMT_A8R8G8B8: return 5;
+ default: return 0;
+ }
+}
+
+void HGE_Impl::_AdjustWindow()
+{
+ RECT *rc;
+ LONG style;
+
+ if(bWindowed) {rc=&rectW; style=styleW; }
+ else {rc=&rectFS; style=styleFS; }
+ SetWindowLong(hwnd, GWL_STYLE, style);
+
+ style=GetWindowLong(hwnd, GWL_EXSTYLE);
+ if(bWindowed)
+ {
+ SetWindowLong(hwnd, GWL_EXSTYLE, style & (~WS_EX_TOPMOST));
+ SetWindowPos(hwnd, HWND_NOTOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED);
+ }
+ else
+ {
+ SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_TOPMOST);
+ SetWindowPos(hwnd, HWND_TOPMOST, rc->left, rc->top, rc->right-rc->left, rc->bottom-rc->top, SWP_FRAMECHANGED);
+ }
+}
+
+void HGE_Impl::_Resize(int width, int height)
+{
+ if(hwndParent)
+ {
+ //if(procFocusLostFunc) procFocusLostFunc();
+
+ d3dppW.BackBufferWidth=width;
+ d3dppW.BackBufferHeight=height;
+ nScreenWidth=width;
+ nScreenHeight=height;
+
+ _SetProjectionMatrix(nScreenWidth, nScreenHeight);
+ _GfxRestore();
+
+ //if(procFocusGainFunc) procFocusGainFunc();
+ }
+}
+
+void HGE_Impl::_GfxDone()
+{
+ CRenderTargetList *target=pTargets, *next_target;
+
+ while(textures) Texture_Free(textures->tex);
+
+ if(pScreenSurf) { pScreenSurf->Release(); pScreenSurf=0; }
+ if(pScreenDepth) { pScreenDepth->Release(); pScreenDepth=0; }
+
+ while(target)
+ {
+ if(target->pTex) target->pTex->Release();
+ if(target->pDepth) target->pDepth->Release();
+ next_target=target->next;
+ delete target;
+ target=next_target;
+ }
+ pTargets=0;
+
+ if(pIB)
+ {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetIndices(NULL,0);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetIndices(NULL);
+#endif
+ pIB->Release();
+ pIB=0;
+ }
+ if(pVB)
+ {
+ if(VertArray) { pVB->Unlock(); VertArray=0; }
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetStreamSource( 0, NULL, 0, sizeof(hgeVertex) );
+#endif
+ pVB->Release();
+ pVB=0;
+ }
+ if(pD3DDevice) { pD3DDevice->Release(); pD3DDevice=0; }
+ if(pD3D) { pD3D->Release(); pD3D=0; }
+}
+
+
+bool HGE_Impl::_GfxRestore()
+{
+ CRenderTargetList *target=pTargets;
+
+ //if(!pD3DDevice) return false;
+ //if(pD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST) return;
+
+ if(pScreenSurf) pScreenSurf->Release();
+ if(pScreenDepth) pScreenDepth->Release();
+
+ while(target)
+ {
+ if(target->pTex) target->pTex->Release();
+ if(target->pDepth) target->pDepth->Release();
+ target=target->next;
+ }
+
+ if(pIB)
+ {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetIndices(NULL,0);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetIndices(NULL);
+#endif
+ pIB->Release();
+ }
+ if(pVB)
+ {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetStreamSource( 0, NULL, sizeof(hgeVertex) );
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetStreamSource( 0, NULL,0, sizeof(hgeVertex) );
+#endif
+ pVB->Release();
+ }
+
+ pD3DDevice->Reset(d3dpp);
+
+ if(!_init_lost()) return false;
+
+ if(procGfxRestoreFunc) return procGfxRestoreFunc();
+
+ return true;
+}
+
+
+bool HGE_Impl::_init_lost()
+{
+ CRenderTargetList *target=pTargets;
+
+// Store render target
+
+ pScreenSurf=0;
+ pScreenDepth=0;
+
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->GetRenderTarget(&pScreenSurf);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->GetRenderTarget(0, &pScreenSurf);
+#endif
+ pD3DDevice->GetDepthStencilSurface(&pScreenDepth);
+
+ while(target)
+ {
+ if(target->pTex)
+ D3DXCreateTexture(pD3DDevice, target->width, target->height, 1, D3DUSAGE_RENDERTARGET,
+ d3dpp->BackBufferFormat, D3DPOOL_DEFAULT, &target->pTex);
+ if(target->pDepth)
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->CreateDepthStencilSurface(target->width, target->height,
+ D3DFMT_D16, D3DMULTISAMPLE_NONE, &target->pDepth);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->CreateDepthStencilSurface(target->width, target->height,
+ D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, false, &target->pDepth, NULL);
+#endif
+ target=target->next;
+ }
+
+// Create Vertex buffer
+#if HGE_DIRECTX_VER == 8
+ if( FAILED (pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE*sizeof(hgeVertex),
+ D3DUSAGE_WRITEONLY,
+ D3DFVF_HGEVERTEX,
+ D3DPOOL_DEFAULT, &pVB )))
+#endif
+#if HGE_DIRECTX_VER == 9
+ if( FAILED (pD3DDevice->CreateVertexBuffer(VERTEX_BUFFER_SIZE*sizeof(hgeVertex),
+ D3DUSAGE_WRITEONLY,
+ D3DFVF_HGEVERTEX,
+ D3DPOOL_DEFAULT,
+ &pVB,
+ NULL)))
+#endif
+ {
+ _PostError("Can't create D3D vertex buffer");
+ return false;
+ }
+
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetVertexShader( D3DFVF_HGEVERTEX );
+ pD3DDevice->SetStreamSource( 0, pVB, sizeof(hgeVertex) );
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetVertexShader( NULL );
+ pD3DDevice->SetFVF( D3DFVF_HGEVERTEX );
+ pD3DDevice->SetStreamSource( 0, pVB, 0, sizeof(hgeVertex) );
+#endif
+
+// Create and setup Index buffer
+
+#if HGE_DIRECTX_VER == 8
+ if( FAILED( pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE*6/4*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT, &pIB ) ) )
+#endif
+#if HGE_DIRECTX_VER == 9
+ if( FAILED( pD3DDevice->CreateIndexBuffer(VERTEX_BUFFER_SIZE*6/4*sizeof(WORD),
+ D3DUSAGE_WRITEONLY,
+ D3DFMT_INDEX16,
+ D3DPOOL_DEFAULT,
+ &pIB,
+ NULL) ) )
+#endif
+ {
+ _PostError("Can't create D3D index buffer");
+ return false;
+ }
+
+ WORD *pIndices, n=0;
+#if HGE_DIRECTX_VER == 8
+ if( FAILED( pIB->Lock( 0, 0, (BYTE**)&pIndices, 0 ) ) )
+#endif
+#if HGE_DIRECTX_VER == 9
+ if( FAILED( pIB->Lock( 0, 0, (VOID**)&pIndices, 0 ) ) )
+#endif
+ {
+ _PostError("Can't lock D3D index buffer");
+ return false;
+ }
+
+ for(int i=0; i<VERTEX_BUFFER_SIZE/4; i++) {
+ *pIndices++=n;
+ *pIndices++=n+1;
+ *pIndices++=n+2;
+ *pIndices++=n+2;
+ *pIndices++=n+3;
+ *pIndices++=n;
+ n+=4;
+ }
+
+ pIB->Unlock();
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetIndices(pIB,0);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetIndices(pIB);
+#endif
+
+// Set common render states
+
+ //pD3DDevice->SetRenderState( D3DRS_LASTPIXEL, FALSE );
+ pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
+ pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
+
+ pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
+ pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
+ pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
+
+ pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
+ pD3DDevice->SetRenderState( D3DRS_ALPHAREF, 0x01 );
+ pD3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
+
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
+
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
+ pD3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
+
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
+ if(bTextureFilter) {
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
+ } else {
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
+ }
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
+ if(bTextureFilter) {
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ } else {
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ }
+#endif
+ nPrim=0;
+ CurPrimType=HGEPRIM_QUADS;
+ CurBlendMode = BLEND_DEFAULT;
+ CurTexture = NULL;
+
+ pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
+ pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
+
+ return true;
+}
View
345 src/core/hge_impl.h
@@ -0,0 +1,345 @@
+/*
+** Haaf's Game Engine 1.8
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Common core implementation header
+*/
+
+
+#ifndef HGE_IMPL_H
+#define HGE_IMPL_H
+
+#include <hge.h>
+#include <stdio.h>
+#include <hge_gapi.h>
+
+
+#define DEMO
+
+#define D3DFVF_HGEVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
+#define VERTEX_BUFFER_SIZE 4000
+
+
+typedef BOOL (WINAPI *GetSystemPowerStatusFunc)(LPSYSTEM_POWER_STATUS);
+
+
+struct CRenderTargetList
+{
+ int width;
+ int height;
+ hgeGAPITexture * pTex;
+ hgeGAPISurface * pDepth;
+ CRenderTargetList * next;
+};
+
+struct CTextureList
+{
+ HTEXTURE tex;
+ int width;
+ int height;
+ CTextureList* next;
+};
+
+struct CResourceList
+{
+ char filename[_MAX_PATH];
+ char password[64];
+ CResourceList* next;
+};
+
+struct CStreamList
+{
+ HSTREAM hstream;
+ void* data;
+ CStreamList* next;
+};
+
+struct CInputEventList
+{
+ hgeInputEvent event;
+ CInputEventList* next;
+};
+
+
+void DInit();
+void DDone();
+bool DFrame();
+
+
+/*
+** HGE Interface implementation
+*/
+class HGE_Impl : public HGE
+{
+public:
+ virtual void CALL Release();
+
+ virtual bool CALL System_Initiate();
+ virtual void CALL System_Shutdown();
+ virtual bool CALL System_Start();
+ virtual void CALL System_SetStateBool (hgeBoolState state, bool value);
+ virtual void CALL System_SetStateFunc (hgeFuncState state, hgeCallback value);
+ virtual void CALL System_SetStateHwnd (hgeHwndState state, HWND value);
+ virtual void CALL System_SetStateInt (hgeIntState state, int value);
+ virtual void CALL System_SetStateString(hgeStringState state, const char *value);
+ virtual bool CALL System_GetStateBool (hgeBoolState );
+ virtual hgeCallback CALL System_GetStateFunc (hgeFuncState );
+ virtual HWND CALL System_GetStateHwnd (hgeHwndState );
+ virtual int CALL System_GetStateInt (hgeIntState );
+ virtual const char* CALL System_GetStateString(hgeStringState);
+ virtual char* CALL System_GetErrorMessage();
+ virtual void CALL System_Log(const char *format, ...);
+ virtual bool CALL System_Launch(const char *url);
+ virtual void CALL System_Snapshot(const char *filename=0);
+
+ virtual void* CALL Resource_Load(const char *filename, DWORD *size=0);
+ virtual void CALL Resource_Free(void *res);
+ virtual bool CALL Resource_AttachPack(const char *filename, const char *password=0);
+ virtual void CALL Resource_RemovePack(const char *filename);
+ virtual void CALL Resource_RemoveAllPacks();
+ virtual char* CALL Resource_MakePath(const char *filename=0);
+ virtual char* CALL Resource_EnumFiles(const char *wildcard=0);
+ virtual char* CALL Resource_EnumFolders(const char *wildcard=0);
+
+ virtual void CALL Ini_SetInt(const char *section, const char *name, int value);
+ virtual int CALL Ini_GetInt(const char *section, const char *name, int def_val);
+ virtual void CALL Ini_SetFloat(const char *section, const char *name, float value);
+ virtual float CALL Ini_GetFloat(const char *section, const char *name, float def_val);
+ virtual void CALL Ini_SetString(const char *section, const char *name, const char *value);
+ virtual char* CALL Ini_GetString(const char *section, const char *name, const char *def_val);
+
+ virtual void CALL Random_Seed(int seed=0);
+ virtual int CALL Random_Int(int min, int max);
+ virtual float CALL Random_Float(float min, float max);
+
+ virtual float CALL Timer_GetTime();
+ virtual float CALL Timer_GetDelta();
+ virtual int CALL Timer_GetFPS();
+
+ virtual HEFFECT CALL Effect_Load(const char *filename, DWORD size=0);
+ virtual void CALL Effect_Free(HEFFECT eff);
+ virtual HCHANNEL CALL Effect_Play(HEFFECT eff);
+ virtual HCHANNEL CALL Effect_PlayEx(HEFFECT eff, int volume=100, int pan=0, float pitch=1.0f, bool loop=false);
+
+ virtual HMUSIC CALL Music_Load(const char *filename, DWORD size=0);
+ virtual void CALL Music_Free(HMUSIC mus);
+ virtual HCHANNEL CALL Music_Play(HMUSIC mus, bool loop, int volume = 100, int order = 0, int row = 0);
+ virtual void CALL Music_SetAmplification(HMUSIC music, int ampl);
+ virtual int CALL Music_GetAmplification(HMUSIC music);
+ virtual int CALL Music_GetLength(HMUSIC music);
+ virtual void CALL Music_SetPos(HMUSIC music, int order, int row);
+ virtual bool CALL Music_GetPos(HMUSIC music, int *order, int *row);
+ virtual void CALL Music_SetInstrVolume(HMUSIC music, int instr, int volume);
+ virtual int CALL Music_GetInstrVolume(HMUSIC music, int instr);
+ virtual void CALL Music_SetChannelVolume(HMUSIC music, int channel, int volume);
+ virtual int CALL Music_GetChannelVolume(HMUSIC music, int channel);
+
+ virtual HSTREAM CALL Stream_Load(const char *filename, DWORD size=0);
+ virtual void CALL Stream_Free(HSTREAM stream);
+ virtual HCHANNEL CALL Stream_Play(HSTREAM stream, bool loop, int volume = 100);
+
+ virtual void CALL Channel_SetPanning(HCHANNEL chn, int pan);
+ virtual void CALL Channel_SetVolume(HCHANNEL chn, int volume);
+ virtual void CALL Channel_SetPitch(HCHANNEL chn, float pitch);
+ virtual void CALL Channel_Pause(HCHANNEL chn);
+ virtual void CALL Channel_Resume(HCHANNEL chn);
+ virtual void CALL Channel_Stop(HCHANNEL chn);
+ virtual void CALL Channel_PauseAll();
+ virtual void CALL Channel_ResumeAll();
+ virtual void CALL Channel_StopAll();
+ virtual bool CALL Channel_IsPlaying(HCHANNEL chn);
+ virtual float CALL Channel_GetLength(HCHANNEL chn);
+ virtual float CALL Channel_GetPos(HCHANNEL chn);
+ virtual void CALL Channel_SetPos(HCHANNEL chn, float fSeconds);
+ virtual void CALL Channel_SlideTo(HCHANNEL channel, float time, int volume, int pan = -101, float pitch = -1);
+ virtual bool CALL Channel_IsSliding(HCHANNEL channel);
+
+ virtual void CALL Input_GetMousePos(float *x, float *y);
+ virtual void CALL Input_SetMousePos(float x, float y);
+ virtual int CALL Input_GetMouseWheel();
+ virtual bool CALL Input_IsMouseOver();
+ virtual bool CALL Input_KeyDown(int key);
+ virtual bool CALL Input_KeyUp(int key);
+ virtual bool CALL Input_GetKeyState(int key);
+ virtual char* CALL Input_GetKeyName(int key);
+ virtual int CALL Input_GetKey();
+ virtual int CALL Input_GetChar();
+ virtual bool CALL Input_GetEvent(hgeInputEvent *event);
+
+ virtual bool CALL Gfx_BeginScene(HTARGET target=0);
+ virtual void CALL Gfx_EndScene();
+ virtual void CALL Gfx_Clear(DWORD color);
+ virtual void CALL Gfx_RenderLine(float x1, float y1, float x2, float y2, DWORD color=0xFFFFFFFF, float z=0.5f);
+ virtual void CALL Gfx_RenderTriple(const hgeTriple *triple);
+ virtual void CALL Gfx_RenderQuad(const hgeQuad *quad);
+ virtual hgeVertex* CALL Gfx_StartBatch(int prim_type, HTEXTURE tex, int blend, int *max_prim);
+ virtual void CALL Gfx_FinishBatch(int nprim);
+ virtual void CALL Gfx_SetClipping(int x=0, int y=0, int w=0, int h=0);
+ virtual void CALL Gfx_SetTransform(float x=0, float y=0, float dx=0, float dy=0, float rot=0, float hscale=0, float vscale=0);
+
+ virtual HTARGET CALL Target_Create(int width, int height, bool zbuffer);
+ virtual void CALL Target_Free(HTARGET target);
+ virtual HTEXTURE CALL Target_GetTexture(HTARGET target);
+
+ virtual HTEXTURE CALL Texture_Create(int width, int height);
+ virtual HTEXTURE CALL Texture_Load(const char *filename, DWORD size=0, bool bMipmap=false);
+ virtual void CALL Texture_Free(HTEXTURE tex);
+ virtual int CALL Texture_GetWidth(HTEXTURE tex, bool bOriginal=false);
+ virtual int CALL Texture_GetHeight(HTEXTURE tex, bool bOriginal=false);
+ virtual DWORD* CALL Texture_Lock(HTEXTURE tex, bool bReadOnly=true, int left=0, int top=0, int width=0, int height=0);
+ virtual void CALL Texture_Unlock(HTEXTURE tex);
+
+ //////// Implementation ////////
+
+ static HGE_Impl* _Interface_Get();
+ void _FocusChange(bool bAct);
+ void _PostError(char *error);
+
+
+ HINSTANCE hInstance;
+ HWND hwnd;
+
+ bool bActive;
+ char szError[256];
+ char szAppPath[_MAX_PATH];
+ char szIniString[256];
+
+
+ // System States
+ bool (*procFrameFunc)();
+ bool (*procRenderFunc)();
+ bool (*procFocusLostFunc)();
+ bool (*procFocusGainFunc)();
+ bool (*procGfxRestoreFunc)();
+ bool (*procExitFunc)();
+ const char* szIcon;
+ char szWinTitle[256];
+ int nScreenWidth;
+ int nScreenHeight;
+ int nScreenBPP;
+ bool bWindowed;
+ bool bZBuffer;
+ bool bTextureFilter;
+ char szIniFile[_MAX_PATH];
+ char szLogFile[_MAX_PATH];
+ bool bUseSound;
+ int nSampleRate;
+ int nFXVolume;
+ int nMusVolume;
+ int nStreamVolume;
+ int nHGEFPS;
+ bool bHideMouse;
+ bool bDontSuspend;
+ HWND hwndParent;
+
+ #ifdef DEMO
+ bool bDMO;
+ #endif
+
+
+ // Power
+ int nPowerStatus;
+ HMODULE hKrnl32;
+ GetSystemPowerStatusFunc lpfnGetSystemPowerStatus;
+
+ void _InitPowerStatus();
+ void _UpdatePowerStatus();
+ void _DonePowerStatus();
+
+
+ // Graphics
+ D3DPRESENT_PARAMETERS* d3dpp;
+
+ D3DPRESENT_PARAMETERS d3dppW;
+ RECT rectW;
+ LONG styleW;
+
+ D3DPRESENT_PARAMETERS d3dppFS;
+ RECT rectFS;
+ LONG styleFS;
+
+ hgeGAPI * pD3D;
+ hgeGAPIDevice * pD3DDevice;
+ hgeGAPIVertexBuffer * pVB;
+ hgeGAPIIndexBuffer * pIB;
+
+ hgeGAPISurface * pScreenSurf;
+ hgeGAPISurface * pScreenDepth;
+ CRenderTargetList* pTargets;
+ CRenderTargetList* pCurTarget;
+
+ D3DXMATRIX matView;
+ D3DXMATRIX matProj;
+
+ CTextureList* textures;
+ hgeVertex* VertArray;
+
+ int nPrim;
+ int CurPrimType;
+ int CurBlendMode;
+ HTEXTURE CurTexture;
+
+ bool _GfxInit();
+ void _GfxDone();
+ bool _GfxRestore();
+ void _AdjustWindow();
+ void _Resize(int width, int height);
+ bool _init_lost();
+ void _render_batch(bool bEndScene=false);
+ int _format_id(D3DFORMAT fmt);
+ void _SetBlendMode(int blend);
+ void _SetProjectionMatrix(int width, int height);
+
+
+ // Audio
+ HINSTANCE hBass;
+ bool bSilent;
+ CStreamList* streams;
+ bool _SoundInit();
+ void _SoundDone();
+ void _SetMusVolume(int vol);
+ void _SetStreamVolume(int vol);
+ void _SetFXVolume(int vol);
+
+
+ // Input
+ int VKey;
+ int Char;
+ int Zpos;
+ float Xpos;
+ float Ypos;
+ bool bMouseOver;
+ bool bCaptured;
+ char keyz[256];
+ CInputEventList* queue;
+ void _UpdateMouse();
+ void _InputInit();
+ void _ClearQueue();
+ void _BuildEvent(int type, int key, int scan, int flags, int x, int y);
+
+
+ // Resources
+ char szTmpFilename[_MAX_PATH];
+ CResourceList* res;
+ HANDLE hSearch;
+ WIN32_FIND_DATA SearchData;
+
+
+ // Timer
+ float fTime;
+ float fDeltaTime;
+ DWORD nFixedDelta;
+ int nFPS;
+ DWORD t0, t0fps, dt;
+ int cfps;
+
+
+private:
+ HGE_Impl();
+};
+
+extern HGE_Impl* pHGE;
+
+#endif
+
View
0 src/core_directx9/ini.cpp → src/core/ini.cpp
File renamed without changes.
View
0 src/core_directx9/input.cpp → src/core/input.cpp
File renamed without changes.
View
0 src/core_directx9/power.cpp → src/core/power.cpp
File renamed without changes.
View
0 src/core_directx9/random.cpp → src/core/random.cpp
File renamed without changes.
View
0 src/core_directx9/resource.cpp → src/core/resource.cpp
File renamed without changes.
View
0 src/core_directx9/sound.cpp → src/core/sound.cpp
File renamed without changes.
View
891 src/core/system.cpp
@@ -0,0 +1,891 @@
+/*
+** Haaf's Game Engine 1.8
+** Copyright (C) 2003-2007, Relish Games
+** hge.relishgames.com
+**
+** Core system functions
+*/
+
+
+#include "hge_impl.h"
+
+
+#define LOWORDINT(n) ((int)((signed short)(LOWORD(n))))
+#define HIWORDINT(n) ((int)((signed short)(HIWORD(n))))
+
+
+const char *WINDOW_CLASS_NAME = "HGE__WNDCLASS";
+
+LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+
+
+int nRef=0;
+HGE_Impl* pHGE=0;
+
+
+
+BOOL APIENTRY DllMain(HANDLE, DWORD, LPVOID)
+{
+ return TRUE;
+}
+
+
+HGE* CALL hgeCreate(int ver)
+{
+ if(ver==HGE_VERSION)
+ return (HGE*)HGE_Impl::_Interface_Get();
+ else
+ return 0;
+}
+
+
+HGE_Impl* HGE_Impl::_Interface_Get()
+{
+ if(!pHGE) pHGE=new HGE_Impl();
+
+ nRef++;
+
+ return pHGE;
+}
+
+
+void CALL HGE_Impl::Release()
+{
+ nRef--;
+
+ if(!nRef)
+ {
+ if(pHGE->hwnd) pHGE->System_Shutdown();
+ Resource_RemoveAllPacks();
+ delete pHGE;
+ pHGE=0;
+ }
+}
+
+
+bool CALL HGE_Impl::System_Initiate()
+{
+ OSVERSIONINFO os_ver;
+ SYSTEMTIME tm;
+ MEMORYSTATUS mem_st;
+ WNDCLASS winclass;
+ int width, height;
+
+ // Log system info
+
+ System_Log("HGE Started..\n");
+
+ System_Log("HGE version: %X.%X", HGE_VERSION>>8, HGE_VERSION & 0xFF);
+ GetLocalTime(&tm);
+ System_Log("Date: %02d.%02d.%d, %02d:%02d:%02d\n", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond);
+
+ System_Log("Application: %s",szWinTitle);
+ os_ver.dwOSVersionInfoSize=sizeof(os_ver);
+ GetVersionEx(&os_ver);
+ System_Log("OS: Windows %ld.%ld.%ld",os_ver.dwMajorVersion,os_ver.dwMinorVersion,os_ver.dwBuildNumber);
+
+ GlobalMemoryStatus(&mem_st);
+ System_Log("Memory: %ldK total, %ldK free\n",mem_st.dwTotalPhys/1024L,mem_st.dwAvailPhys/1024L);
+
+
+ // Register window class
+
+ winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ winclass.lpfnWndProc = WindowProc;
+ winclass.cbClsExtra = 0;
+ winclass.cbWndExtra = 0;
+ winclass.hInstance = hInstance;
+ winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ winclass.lpszMenuName = NULL;
+ winclass.lpszClassName = WINDOW_CLASS_NAME;
+ if(szIcon) winclass.hIcon = LoadIcon(hInstance, szIcon);
+ else winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+
+ if (!RegisterClass(&winclass)) {
+ _PostError("Can't register window class");
+ return false;
+ }
+
+ // Create window
+
+ width=nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME)*2;
+ height=nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
+
+ rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2;
+ rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2;
+ rectW.right=rectW.left+width;
+ rectW.bottom=rectW.top+height;
+ styleW=WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE; //WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX;
+
+ rectFS.left=0;
+ rectFS.top=0;
+ rectFS.right=nScreenWidth;
+ rectFS.bottom=nScreenHeight;
+ styleFS=WS_POPUP|WS_VISIBLE; //WS_POPUP
+
+ if(hwndParent)
+ {
+ rectW.left=0;
+ rectW.top=0;
+ rectW.right=nScreenWidth;
+ rectW.bottom=nScreenHeight;
+ styleW=WS_CHILD|WS_VISIBLE;
+ bWindowed=true;
+ }
+
+ if(bWindowed)
+ hwnd = CreateWindowEx(0, WINDOW_CLASS_NAME, szWinTitle, styleW,
+ rectW.left, rectW.top, rectW.right-rectW.left, rectW.bottom-rectW.top,
+ hwndParent, NULL, hInstance, NULL);
+ else
+ hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, szWinTitle, styleFS,
+ 0, 0, 0, 0,
+ NULL, NULL, hInstance, NULL);
+ if (!hwnd)
+ {
+ _PostError("Can't create window");
+ return false;
+ }
+
+ ShowWindow(hwnd, SW_SHOW);
+
+ // Init subsystems
+
+ timeBeginPeriod(1);
+ Random_Seed();
+ _InitPowerStatus();
+ _InputInit();
+ if(!_GfxInit()) { System_Shutdown(); return false; }
+ if(!_SoundInit()) { System_Shutdown(); return false; }
+
+ System_Log("Init done.\n");
+
+ fTime=0.0f;
+ t0=t0fps=timeGetTime();
+ dt=cfps=0;
+ nFPS=0;
+
+ // Show splash
+
+#ifdef DEMO
+
+ bool (*func)();
+ bool (*rfunc)();
+ HWND hwndTmp;
+
+ if(pHGE->bDMO)
+ {
+ Sleep(200);
+ func=(bool(*)())pHGE->System_GetStateFunc(HGE_FRAMEFUNC);
+ rfunc=(bool(*)())pHGE->System_GetStateFunc(HGE_RENDERFUNC);
+ hwndTmp=hwndParent; hwndParent=0;
+ pHGE->System_SetStateFunc(HGE_FRAMEFUNC, DFrame);
+ pHGE->System_SetStateFunc(HGE_RENDERFUNC, 0);
+ DInit();
+ pHGE->System_Start();
+ DDone();
+ hwndParent=hwndTmp;
+ pHGE->System_SetStateFunc(HGE_FRAMEFUNC, func);
+ pHGE->System_SetStateFunc(HGE_RENDERFUNC, rfunc);
+ }
+
+#endif
+
+ // Done
+
+ return true;
+}
+
+void CALL HGE_Impl::System_Shutdown()
+{
+ System_Log("\nFinishing..");
+
+ timeEndPeriod(1);
+ if(hSearch) { FindClose(hSearch); hSearch=0; }
+ _ClearQueue();
+ _SoundDone();
+ _GfxDone();
+ _DonePowerStatus();
+
+ if(hwnd)
+ {
+ //ShowWindow(hwnd, SW_HIDE);
+ //SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
+ //ShowWindow(hwnd, SW_SHOW);
+ DestroyWindow(hwnd);
+ hwnd=0;
+ }
+
+ if(hInstance) UnregisterClass(WINDOW_CLASS_NAME, hInstance);
+
+ System_Log("The End.");
+}
+
+
+bool CALL HGE_Impl::System_Start()
+{
+ MSG msg;
+
+ if(!hwnd)
+ {
+ _PostError("System_Start: System_Initiate wasn't called");
+ return false;
+ }
+
+ if(!procFrameFunc) {
+ _PostError("System_Start: No frame function defined");
+ return false;
+ }
+
+ bActive=true;
+
+ // MAIN LOOP
+
+ for(;;)
+ {
+
+ // Process window messages if not in "child mode"
+ // (if in "child mode" the parent application will do this for us)
+
+ if(!hwndParent)
+ {
+ if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
+ {
+ if (msg.message == WM_QUIT) break;
+ // TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ continue;
+ }
+ }
+
+ // Check if mouse is over HGE window for Input_IsMouseOver
+
+ _UpdateMouse();
+
+ // If HGE window is focused or we have the "don't suspend" state - process the main loop
+
+ if(bActive || bDontSuspend)
+ {
+ // Ensure we have at least 1ms time step
+ // to not confuse user's code with 0
+
+ do { dt=timeGetTime() - t0; } while(dt < 1);
+
+ // If we reached the time for the next frame
+ // or we just run in unlimited FPS mode, then
+ // do the stuff
+
+ if(dt >= nFixedDelta)
+ {
+ // fDeltaTime = time step in seconds returned by Timer_GetDelta
+
+ fDeltaTime=dt/1000.0f;
+
+ // Cap too large time steps usually caused by lost focus to avoid jerks
+
+ if(fDeltaTime > 0.2f)
+ {
+ fDeltaTime = nFixedDelta ? nFixedDelta/1000.0f : 0.01f;
+ }
+
+ // Update time counter returned Timer_GetTime
+
+ fTime += fDeltaTime;
+
+ // Store current time for the next frame
+ // and count FPS
+
+ t0=timeGetTime();
+ if(t0-t0fps <= 1000) cfps++;
+ else
+ {
+ nFPS=cfps; cfps=0; t0fps=t0;
+ _UpdatePowerStatus();
+ }
+
+ // Do user's stuff
+
+ if(procFrameFunc()) break;
+ if(procRenderFunc) procRenderFunc();
+
+ // If if "child mode" - return after processing single frame
+
+ if(hwndParent) break;
+
+ // Clean up input events that were generated by
+ // WindowProc and weren't handled by user's code
+
+ _ClearQueue();
+
+ // If we use VSYNC - we could afford a little
+ // sleep to lower CPU usage
+
+ // if(!bWindowed && nHGEFPS==HGEFPS_VSYNC) Sleep(1);
+ }
+
+ // If we have a fixed frame rate and the time
+ // for the next frame isn't too close, sleep a bit
+
+ else
+ {
+ if(nFixedDelta && dt+3 < nFixedDelta) Sleep(1);
+ }
+ }
+
+ // If main loop is suspended - just sleep a bit
+ // (though not too much to allow instant window
+ // redraw if requested by OS)
+
+ else Sleep(1);
+ }
+
+ _ClearQueue();
+
+ bActive=false;
+
+ return true;
+}
+
+void CALL HGE_Impl::System_SetStateBool(hgeBoolState state, bool value)
+{
+ switch(state)
+ {
+ case HGE_WINDOWED: if(VertArray || hwndParent) break;
+ if(pD3DDevice && bWindowed != value)
+ {
+ if(d3dppW.BackBufferFormat==D3DFMT_UNKNOWN || d3dppFS.BackBufferFormat==D3DFMT_UNKNOWN) break;
+
+ if(bWindowed) GetWindowRect(hwnd, &rectW);
+ bWindowed=value;
+ if(bWindowed) d3dpp=&d3dppW;
+ else d3dpp=&d3dppFS;
+
+ if(_format_id(d3dpp->BackBufferFormat) < 4) nScreenBPP=16;
+ else nScreenBPP=32;
+
+ _GfxRestore();
+ _AdjustWindow();
+ }
+ else bWindowed=value;
+ break;
+
+ case HGE_ZBUFFER: if(!pD3DDevice) bZBuffer=value;
+ break;
+
+ case HGE_TEXTUREFILTER: bTextureFilter=value;
+ if(pD3DDevice)
+ {
+ _render_batch();
+ if(bTextureFilter) {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+#endif
+ } else {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTEXF_POINT);
+ pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTEXF_POINT);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+#endif
+ }
+ }
+ break;
+
+ case HGE_USESOUND: if(bUseSound!=value)
+ {
+ bUseSound=value;
+ if(bUseSound && hwnd) _SoundInit();
+ if(!bUseSound && hwnd) _SoundDone();
+ }
+ break;
+
+ case HGE_HIDEMOUSE: bHideMouse=value; break;
+
+ case HGE_DONTSUSPEND: bDontSuspend=value; break;
+
+ #ifdef DEMO
+ case HGE_SHOWSPLASH: bDMO=value; break;
+ #endif
+ }
+}
+
+void CALL HGE_Impl::System_SetStateFunc(hgeFuncState state, hgeCallback value)
+{
+ switch(state)
+ {
+ case HGE_FRAMEFUNC: procFrameFunc=value; break;
+ case HGE_RENDERFUNC: procRenderFunc=value; break;
+ case HGE_FOCUSLOSTFUNC: procFocusLostFunc=value; break;
+ case HGE_FOCUSGAINFUNC: procFocusGainFunc=value; break;
+ case HGE_GFXRESTOREFUNC: procGfxRestoreFunc=value; break;
+ case HGE_EXITFUNC: procExitFunc=value; break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateHwnd(hgeHwndState state, HWND value)
+{
+ switch(state)
+ {
+ case HGE_HWNDPARENT: if(!hwnd) hwndParent=value; break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateInt(hgeIntState state, int value)
+{
+ switch(state)
+ {
+ case HGE_SCREENWIDTH: if(!pD3DDevice) nScreenWidth=value; break;
+
+ case HGE_SCREENHEIGHT: if(!pD3DDevice) nScreenHeight=value; break;
+
+ case HGE_SCREENBPP: if(!pD3DDevice) nScreenBPP=value; break;
+
+ case HGE_SAMPLERATE: if(!hBass) nSampleRate=value;
+ break;
+
+ case HGE_FXVOLUME: nFXVolume=value;
+ _SetFXVolume(nFXVolume);
+ break;
+
+ case HGE_MUSVOLUME: nMusVolume=value;
+ _SetMusVolume(nMusVolume);
+ break;
+
+ case HGE_STREAMVOLUME: nStreamVolume=value;
+ _SetStreamVolume(nStreamVolume);
+ break;
+
+ case HGE_FPS: if(VertArray) break;
+
+ if(pD3DDevice)
+ {
+ if((nHGEFPS>=0 && value <0) || (nHGEFPS<0 && value>=0))
+ {
+ if(value==HGEFPS_VSYNC)
+ {
+#if HGE_DIRECTX_VER == 8
+ d3dppW.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
+ d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+#endif
+#if HGE_DIRECTX_VER == 9
+ d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
+ d3dppW.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+ d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
+#endif
+ }
+ else
+ {
+ d3dppW.SwapEffect = D3DSWAPEFFECT_COPY;
+#if HGE_DIRECTX_VER == 8
+ d3dppFS.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+#endif
+#if HGE_DIRECTX_VER == 9
+ d3dppFS.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
+#endif
+ }
+ //if(procFocusLostFunc) procFocusLostFunc();
+ _GfxRestore();
+ //if(procFocusGainFunc) procFocusGainFunc();
+ }
+ }
+ nHGEFPS=value;
+ if(nHGEFPS>0) nFixedDelta=int(1000.0f/value);
+ else nFixedDelta=0;
+ break;
+ }
+}
+
+void CALL HGE_Impl::System_SetStateString(hgeStringState state, const char *value)
+{
+ FILE *hf;
+
+ switch(state)
+ {
+ case HGE_ICON: szIcon=value;
+ if(pHGE->hwnd) SetClassLong(pHGE->hwnd, GCL_HICON, (LONG)LoadIcon(pHGE->hInstance, szIcon));
+ break;
+ case HGE_TITLE: strcpy(szWinTitle,value);
+ if(pHGE->hwnd) SetWindowText(pHGE->hwnd, szWinTitle);
+ break;
+ case HGE_INIFILE: if(value) strcpy(szIniFile,Resource_MakePath(value));
+ else szIniFile[0]=0;
+ break;
+ case HGE_LOGFILE: if(value)
+ {
+ strcpy(szLogFile,Resource_MakePath(value));
+ hf=fopen(szLogFile, "w");
+ if(!hf) szLogFile[0]=0;
+ else fclose(hf);
+ }
+ else szLogFile[0]=0;
+ break;
+ }
+}
+
+bool CALL HGE_Impl::System_GetStateBool(hgeBoolState state)
+{
+ switch(state)
+ {
+ case HGE_WINDOWED: return bWindowed;
+ case HGE_ZBUFFER: return bZBuffer;
+ case HGE_TEXTUREFILTER: return bTextureFilter;
+ case HGE_USESOUND: return bUseSound;
+ case HGE_DONTSUSPEND: return bDontSuspend;
+ case HGE_HIDEMOUSE: return bHideMouse;
+
+ #ifdef DEMO
+ case HGE_SHOWSPLASH: return bDMO;
+ #endif
+ }
+
+ return false;
+}
+
+hgeCallback CALL HGE_Impl::System_GetStateFunc(hgeFuncState state)
+{
+ switch(state)
+ {
+ case HGE_FRAMEFUNC: return procFrameFunc;
+ case HGE_RENDERFUNC: return procRenderFunc;
+ case HGE_FOCUSLOSTFUNC: return procFocusLostFunc;
+ case HGE_FOCUSGAINFUNC: return procFocusGainFunc;
+ case HGE_EXITFUNC: return procExitFunc;
+ }
+
+ return NULL;
+}
+
+HWND CALL HGE_Impl::System_GetStateHwnd(hgeHwndState state)
+{
+ switch(state)
+ {
+ case HGE_HWND: return hwnd;
+ case HGE_HWNDPARENT: return hwndParent;
+ }
+
+ return 0;
+}
+
+int CALL HGE_Impl::System_GetStateInt(hgeIntState state)
+{
+ switch(state)
+ {
+ case HGE_SCREENWIDTH: return nScreenWidth;
+ case HGE_SCREENHEIGHT: return nScreenHeight;
+ case HGE_SCREENBPP: return nScreenBPP;
+ case HGE_SAMPLERATE: return nSampleRate;
+ case HGE_FXVOLUME: return nFXVolume;
+ case HGE_MUSVOLUME: return nMusVolume;
+ case HGE_STREAMVOLUME: return nStreamVolume;
+ case HGE_FPS: return nHGEFPS;
+ case HGE_POWERSTATUS: return nPowerStatus;
+ }
+
+ return 0;
+}
+
+const char* CALL HGE_Impl::System_GetStateString(hgeStringState state) {
+ switch(state) {
+ case HGE_ICON: return szIcon;
+ case HGE_TITLE: return szWinTitle;
+ case HGE_INIFILE: if(szIniFile[0]) return szIniFile;
+ else return 0;
+ case HGE_LOGFILE: if(szLogFile[0]) return szLogFile;
+ else return 0;
+ }
+
+ return NULL;
+}
+
+char* CALL HGE_Impl::System_GetErrorMessage()
+{
+ return szError;
+}
+
+void CALL HGE_Impl::System_Log(const char *szFormat, ...)
+{
+ FILE *hf = NULL;
+ va_list ap;
+
+ if(!szLogFile[0]) return;
+
+ hf = fopen(szLogFile, "a");
+ if(!hf) return;
+
+ va_start(ap, szFormat);
+ vfprintf(hf, szFormat, ap);
+ va_end(ap);
+
+ fprintf(hf, "\n");
+
+ fclose(hf);
+}
+
+bool CALL HGE_Impl::System_Launch(const char *url)
+{
+ if((DWORD)ShellExecute(pHGE->hwnd, NULL, url, NULL, NULL, SW_SHOWMAXIMIZED)>32) return true;
+ else return false;
+}
+
+void CALL HGE_Impl::System_Snapshot(const char *filename)
+{
+ hgeGAPISurface * pSurf;
+ char *shotname, tempname[_MAX_PATH];
+ int i;
+
+ if(!filename)
+ {
+ i=0;
+ shotname=Resource_EnumFiles("shot???.bmp");
+ while(shotname)
+ {
+ i++;
+ shotname=Resource_EnumFiles();
+ }
+ sprintf(tempname, "shot%03d.bmp", i);
+ filename=Resource_MakePath(tempname);
+ }
+
+ if(pD3DDevice)
+ {
+#if HGE_DIRECTX_VER == 8
+ pD3DDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf);
+#endif
+#if HGE_DIRECTX_VER == 9
+ pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf);
+#endif
+ D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurf, NULL, NULL);
+ pSurf->Release();
+ }
+}
+
+//////// Implementation ////////
+
+
+HGE_Impl::HGE_Impl()
+{
+ hInstance=GetModuleHandle(0);
+ hwnd=0;
+ bActive=false;
+ szError[0]=0;
+
+ pD3D=0;
+ pD3DDevice=0;
+ d3dpp=0;
+ pTargets=0;
+ pCurTarget=0;
+ pScreenSurf=0;
+ pScreenDepth=0;
+ pVB=0;
+ pIB=0;
+ VertArray=0;
+ textures=0;
+
+ hBass=0;