DOSBox-X
|
00001 /* 00002 * Direct3D rendering code by gulikoza 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #ifndef __DIRECT3D_H_ 00020 #define __DIRECT3D_H_ 00021 00022 #include <d3d9.h> 00023 #include <d3dx9math.h> 00024 #include "dosbox.h" 00025 #include "hq2x_d3d.h" 00026 00027 #define LOG_D3D 0 // Set this to 1 to enable D3D debug messages 00028 #define D3D_THREAD 1 // Set this to 1 to thread Direct3D 00029 00030 #if LOG_D3D 00031 #include <io.h> 00032 #include <fcntl.h> 00033 #include <stdio.h> 00034 #endif 00035 00036 #if D3D_THREAD 00037 #include "SDL_thread.h" 00038 #endif 00039 00040 #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } 00041 00042 #if defined (_MSC_VER) /* MS Visual C++ */ 00043 #define strcasecmp(a,b) stricmp(a,b) 00044 #endif 00045 00046 // Vertex format 00047 #define D3DFVF_TLVERTEX D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1 00048 00049 #if C_D3DSHADERS 00050 #include "ScalingEffect.h" 00051 #else 00052 #define D3DXMATRIX D3DMATRIX 00053 #define D3DXVECTOR3 vec3f 00054 #define D3DXVECTOR2 vec2f 00055 #define D3DXMatrixOrthoOffCenterLH MatrixOrthoOffCenterLH 00056 #define D3DXMatrixTranslation MatrixTranslation 00057 #define D3DXMatrixScaling MatrixScaling 00058 00059 struct vec3f { 00060 float x, y, z; 00061 vec3f() { } 00062 vec3f(float vx, float vy, float vz) 00063 : x(vx), y(vy), z(vz) { } 00064 }; 00065 00066 struct vec2f { 00067 float x, y; 00068 vec2f() { } 00069 vec2f(float vx, float vy) 00070 : x(vx), y(vy) { } 00071 }; 00072 00073 #endif 00074 00075 class CDirect3D { 00076 private: 00077 00078 // globals 00079 HMODULE mhmodDX9 = NULL; 00080 IDirect3D9* pD3D9 = NULL; 00081 IDirect3DDevice9* pD3DDevice9 = NULL; 00082 00083 D3DPRESENT_PARAMETERS d3dpp = {}; // Present parameters 00084 D3DLOCKED_RECT d3dlr = {}; // Texture lock rectangle 00085 00086 HWND hwnd = NULL; // DOSBox window 00087 DWORD dwX = 0, dwY = 0; // X,Y position 00088 DWORD dwWidth, dwHeight; // DOSBox framebuffer size 00089 DWORD dwScaledWidth = 0, dwScaledHeight = 0; // D3D backbuffer size 00090 const Bit16u* changedLines = NULL; 00091 00092 int backbuffer_clear_countdown = 0; 00093 00094 // display modes 00095 D3DDISPLAYMODE* modes; 00096 unsigned int iMode = 0; 00097 DWORD dwNumModes = 0; 00098 00099 bool deviceLost; 00100 00101 // vertex stuff 00102 IDirect3DVertexBuffer9* vertexBuffer; // VertexBuffer 00103 00104 // Custom vertex 00105 struct TLVERTEX { 00106 D3DXVECTOR3 position; // vertex position 00107 D3DCOLOR diffuse; 00108 D3DXVECTOR2 texcoord; // texture coords 00109 }; 00110 00111 // Projection matrices 00112 D3DXMATRIX m_matProj; 00113 D3DXMATRIX m_matWorld; 00114 D3DXMATRIX m_matView; 00115 00116 #if C_D3DSHADERS 00117 D3DXMATRIX m_matPreProj; 00118 D3DXMATRIX m_matPreView; 00119 D3DXMATRIX m_matPreWorld; 00120 00121 // Pixel shader 00122 std::string pshader; 00123 ScalingEffect* psEffect; 00124 LPDIRECT3DTEXTURE9 lpWorkTexture1; 00125 LPDIRECT3DTEXTURE9 lpWorkTexture2; 00126 LPDIRECT3DVOLUMETEXTURE9 lpHq2xLookupTexture; 00127 #if LOG_D3D 00128 LPDIRECT3DTEXTURE9 lpDebugTexture; 00129 #endif 00130 #endif 00131 LPDIRECT3DTEXTURE9 lpTexture; // D3D texture 00132 bool psEnabled; 00133 bool preProcess; 00134 00135 // function declarations 00136 HRESULT InitD3D(void); 00137 00138 HRESULT RestoreDeviceObjects(void); 00139 HRESULT InvalidateDeviceObjects(void); 00140 HRESULT CreateDisplayTexture(void); 00141 HRESULT CreateVertex(void); 00142 #if !(C_D3DSHADERS) 00143 D3DXMATRIX* MatrixOrthoOffCenterLH(D3DXMATRIX*, float, float, float, float, float, float); 00144 D3DXMATRIX* MatrixScaling(D3DXMATRIX*, float, float, float); 00145 D3DXMATRIX* MatrixTranslation(D3DXMATRIX*, float, float, float); 00146 #endif 00147 00148 void SetupSceneScaled(void); 00149 bool D3DSwapBuffers(void); 00150 00151 #if D3D_THREAD 00152 // Thread entry point must be static 00153 static int EntryPoint(void * pthis) { CDirect3D * pt = (CDirect3D *)pthis; return pt->Start(); } 00154 HRESULT Wait(bool unlock = true); 00155 int Start(void); 00156 00157 SDL_Thread *thread; 00158 CRITICAL_SECTION cs; 00159 SDL_semaphore *thread_sem, *thread_ack; 00160 00161 volatile enum D3D_state { D3D_IDLE = 0, D3D_LOADPS, D3D_LOCK, D3D_UNLOCK } thread_command; 00162 volatile bool thread_run, wait; 00163 volatile HRESULT thread_hr = 0; 00164 #if LOG_D3D 00165 void EnterLOGCriticalSection(LPCRITICAL_SECTION lpCriticalSection, int); 00166 #endif 00167 #endif 00168 00169 HRESULT LoadPixelShader(void); 00170 HRESULT Resize3DEnvironment(void); 00171 HRESULT LockTexture(void); 00172 bool UnlockTexture(void); 00173 void DestroyD3D(void); 00174 00175 public: 00176 00177 // texture stuff 00178 DWORD dwTexHeight = 0, dwTexWidth = 0; 00179 00180 bool square = false, pow2 = false, dynamic = false, bpp16; // Texture limitations 00181 Bit8s aspect, autofit = 0; 00182 00183 // Pixel shader status 00184 bool psActive; 00185 00186 // function declarations 00187 HRESULT InitializeDX(HWND, bool); 00188 HRESULT LoadPixelShader(const char*, double, double, bool forced=false); 00189 HRESULT Resize3DEnvironment(Bitu, Bitu, Bitu, Bitu, Bitu, Bitu, Bitu, Bitu, bool fullscreen=false); 00190 bool LockTexture(Bit8u * & pixels,Bitu & pitch); 00191 bool UnlockTexture(const Bit16u *changed); 00192 00193 CDirect3D(Bit32u width = 640, Bit32u height = 400):dwWidth(width),dwHeight(height) { 00194 mhmodDX9 = NULL; 00195 pD3D9 = NULL; 00196 pD3DDevice9 = NULL; 00197 modes = NULL; 00198 vertexBuffer = NULL; 00199 00200 deviceLost = false; 00201 00202 bpp16 = false; 00203 aspect = 0; 00204 lpTexture = NULL; 00205 00206 psEnabled = false; 00207 psActive = false; 00208 preProcess = false; 00209 00210 #if C_D3DSHADERS 00211 lpWorkTexture1 = NULL; 00212 lpWorkTexture2 = NULL; 00213 lpHq2xLookupTexture = NULL; 00214 #if LOG_D3D 00215 lpDebugTexture = NULL; 00216 #endif 00217 pshader.clear(); 00218 psEffect = NULL; 00219 #endif 00220 00221 #if D3D_THREAD 00222 thread = NULL; 00223 wait = false; 00224 thread_run = false; 00225 thread_command = D3D_IDLE; 00226 00227 InitializeCriticalSection(&cs); 00228 thread_sem = SDL_CreateSemaphore(0); 00229 thread_ack = SDL_CreateSemaphore(0); 00230 #endif 00231 00232 } 00233 00234 void UpdateRectFromSDLSurface(int x,int y,int w,int h); 00235 void UpdateRectToSDLSurface(int x,int y,int w,int h); 00236 00237 bool getForceUpdate(void) { 00238 #if C_D3DSHADERS 00239 if (psEffect) return psEffect->getForceUpdate(); 00240 #endif 00241 return false; 00242 } 00243 00244 ~CDirect3D() { 00245 #if LOG_D3D 00246 LOG_MSG("D3D:Shutting down Direct3D"); 00247 #endif 00248 DestroyD3D(); 00249 00250 #if D3D_THREAD 00251 DeleteCriticalSection(&cs); 00252 SDL_DestroySemaphore(thread_sem); 00253 SDL_DestroySemaphore(thread_ack); 00254 #endif 00255 00256 // Unload d3d9.dll 00257 if (mhmodDX9) { 00258 FreeLibrary(mhmodDX9); 00259 mhmodDX9 = NULL; 00260 } 00261 } 00262 }; 00263 00264 #endif // __DIRECT3D_H_