1
0

support.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. LICENSE
  3. -------
  4. Copyright 2005-2013 Nullsoft, Inc.
  5. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. * Redistributions of source code must retain the above copyright notice,
  9. this list of conditions and the following disclaimer.
  10. * Redistributions in binary form must reproduce the above copyright notice,
  11. this list of conditions and the following disclaimer in the documentation
  12. and/or other materials provided with the distribution.
  13. * Neither the name of Nullsoft nor the names of its contributors may be used to
  14. endorse or promote products derived from this software without specific prior written permission.
  15. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  16. IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  18. CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  21. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  22. OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #include "support.h"
  25. #include "utility.h"
  26. #include "../Winamp/wa_ipc.h"
  27. bool g_bDebugOutput = false;
  28. bool g_bDumpFileCleared = false;
  29. //---------------------------------------------------
  30. void PrepareFor3DDrawing(
  31. IDirect3DDevice9 *pDevice,
  32. int viewport_width,
  33. int viewport_height,
  34. float fov_in_degrees,
  35. float near_clip,
  36. float far_clip,
  37. D3DXVECTOR3* pvEye,
  38. D3DXVECTOR3* pvLookat,
  39. D3DXVECTOR3* pvUp
  40. )
  41. {
  42. // This function sets up DirectX up for 3D rendering.
  43. // Only call it once per frame, as it is VERY slow.
  44. // INPUTS:
  45. // pDevice a pointer to the D3D device
  46. // viewport_width the width of the client area of the window
  47. // viewport_height the height of the client area of the window
  48. // fov_in_degrees the field of view, in degrees
  49. // near_clip the distance to the near clip plane; should be > 0!
  50. // far_clip the distance to the far clip plane
  51. // eye the eyepoint coordinates, in world space
  52. // lookat the point toward which the eye is looking, in world space
  53. // up a vector indicating which dir. is up; usually <0,1,0>
  54. //
  55. // What this function does NOT do:
  56. // 1. set the current texture (SetTexture)
  57. // 2. set up the texture stages for texturing (SetTextureStageState)
  58. // 3. set the current vertex format (SetVertexShader)
  59. // 4. set up the world matrix (SetTransform(D3DTS_WORLD, &my_world_matrix))
  60. // set up render state to some nice defaults:
  61. {
  62. // some defaults
  63. pDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  64. pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
  65. pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
  66. pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  67. pDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
  68. pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  69. pDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE );
  70. pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  71. pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  72. pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  73. // turn fog off
  74. pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  75. pDevice->SetRenderState( D3DRS_RANGEFOGENABLE, FALSE );
  76. // turn on high-quality bilinear interpolations
  77. pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  78. pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  79. pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  80. pDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  81. pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  82. pDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  83. }
  84. // set up view & projection matrices (but not the world matrix!)
  85. {
  86. // if the window is not square, instead of distorting the scene,
  87. // clip it so that the longer dimension of the window has the
  88. // regular FOV, and the shorter dimension has a reduced FOV.
  89. float fov_x = fov_in_degrees * 3.1415927f/180.0f;
  90. float fov_y = fov_in_degrees * 3.1415927f/180.0f;
  91. float aspect = (float)viewport_height / (float)viewport_width;
  92. if (aspect < 1)
  93. fov_y *= aspect;
  94. else
  95. fov_x /= aspect;
  96. if (near_clip < 0.1f)
  97. near_clip = 0.1f;
  98. if (far_clip < near_clip + 1.0f)
  99. far_clip = near_clip + 1.0f;
  100. D3DXMATRIX proj;
  101. MakeProjectionMatrix(&proj, near_clip, far_clip, fov_x, fov_y);
  102. pDevice->SetTransform(D3DTS_PROJECTION, &proj);
  103. D3DXMATRIX view;
  104. pMatrixLookAtLH(&view, pvEye, pvLookat, pvUp);
  105. pDevice->SetTransform(D3DTS_VIEW, &view);
  106. // Optimization note: "You can minimize the number of required calculations
  107. // by concatenating your world and view matrices into a world-view matrix
  108. // that you set as the world matrix, and then setting the view matrix
  109. // to the identity."
  110. //D3DXMatrixMultiply(&world, &world, &view);
  111. //D3DXMatrixIdentity(&view);
  112. }
  113. }
  114. void PrepareFor2DDrawing(IDirect3DDevice9 *pDevice)
  115. {
  116. // New 2D drawing area will have x,y coords in the range <-1,-1> .. <1,1>
  117. // +--------+ Y=-1
  118. // | |
  119. // | screen | Z=0: front of scene
  120. // | | Z=1: back of scene
  121. // +--------+ Y=1
  122. // X=-1 X=1
  123. // NOTE: After calling this, be sure to then call (at least):
  124. // 1. SetVertexShader()
  125. // 2. SetTexture(), if you need it
  126. // before rendering primitives!
  127. // Also, be sure your sprites have a z coordinate of 0.
  128. pDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
  129. pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
  130. pDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
  131. pDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
  132. pDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  133. pDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  134. pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
  135. pDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
  136. pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
  137. pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  138. pDevice->SetRenderState( D3DRS_LOCALVIEWER, FALSE );
  139. pDevice->SetTexture(0, NULL);
  140. pDevice->SetTexture(1, NULL);
  141. pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
  142. pDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);//D3DTEXF_LINEAR);
  143. pDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
  144. pDevice->SetTextureStageState(1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
  145. pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  146. pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  147. pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );
  148. pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  149. pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  150. pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
  151. pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  152. pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  153. // set up for 2D drawing:
  154. {
  155. D3DXMATRIX Ortho2D;
  156. D3DXMATRIX Identity;
  157. pMatrixOrthoLH(&Ortho2D, 2.0f, -2.0f, 0.0f, 1.0f);
  158. D3DXMatrixIdentity(&Identity);
  159. pDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
  160. pDevice->SetTransform(D3DTS_WORLD, &Identity);
  161. pDevice->SetTransform(D3DTS_VIEW, &Identity);
  162. }
  163. }
  164. //---------------------------------------------------
  165. void MakeWorldMatrix( D3DXMATRIX* pOut,
  166. float xpos, float ypos, float zpos,
  167. float sx, float sy, float sz,
  168. float pitch, float yaw, float roll)
  169. {
  170. /*
  171. * The m_xPos, m_yPos, m_zPos variables contain the model's
  172. * location in world coordinates.
  173. * The m_fPitch, m_fYaw, and m_fRoll variables are floats that
  174. * contain the model's orientation in terms of pitch, yaw, and roll
  175. * angles, in radians.
  176. */
  177. D3DXMATRIX MatTemp;
  178. D3DXMatrixIdentity(pOut);
  179. // 1. first, rotation
  180. if (pitch || yaw || roll)
  181. {
  182. D3DXMATRIX MatRot;
  183. D3DXMatrixIdentity(&MatRot);
  184. pMatrixRotationX(&MatTemp, pitch); // Pitch
  185. pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
  186. pMatrixRotationY(&MatTemp, yaw); // Yaw
  187. pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
  188. pMatrixRotationZ(&MatTemp, roll); // Roll
  189. pMatrixMultiply(&MatRot, &MatRot, &MatTemp);
  190. pMatrixMultiply(pOut, pOut, &MatRot);
  191. }
  192. // 2. then, scaling
  193. pMatrixScaling(&MatTemp, sx, sy, sz);
  194. pMatrixMultiply(pOut, pOut, &MatTemp);
  195. // 3. last, translation to final world pos.
  196. pMatrixTranslation(&MatTemp, xpos, ypos, zpos);
  197. pMatrixMultiply(pOut, pOut, &MatTemp);
  198. }
  199. void MakeProjectionMatrix( D3DXMATRIX* pOut,
  200. const float near_plane, // Distance to near clipping plane
  201. const float far_plane, // Distance to far clipping plane
  202. const float fov_horiz, // Horizontal field of view angle, in radians
  203. const float fov_vert) // Vertical field of view angle, in radians
  204. {
  205. float w = (float)1/tanf(fov_horiz*0.5f); // 1/tan(x) == cot(x)
  206. float h = (float)1/tanf(fov_vert*0.5f); // 1/tan(x) == cot(x)
  207. float Q = far_plane/(far_plane - near_plane);
  208. ZeroMemory(pOut, sizeof(D3DXMATRIX));
  209. pOut->_11 = w;
  210. pOut->_22 = h;
  211. pOut->_33 = Q;
  212. pOut->_43 = -Q*near_plane;
  213. pOut->_34 = 1;
  214. }
  215. void GetWinampSongTitle(HWND hWndWinamp, wchar_t *szSongTitle, int nSize)
  216. {
  217. szSongTitle[0] = 0;
  218. lstrcpynW(szSongTitle, (wchar_t*)SendMessage(hWndWinamp, WM_WA_IPC,
  219. SendMessage(hWndWinamp, WM_WA_IPC, 0 , IPC_GETLISTPOS),
  220. IPC_GETPLAYLISTTITLEW), nSize);
  221. }
  222. void GetWinampSongPosAsText(HWND hWndWinamp, wchar_t *szSongPos)
  223. {
  224. // note: size(szSongPos[]) must be at least 64.
  225. szSongPos[0] = 0;
  226. int nSongPosMS = SendMessage(hWndWinamp,WM_USER,0,105);
  227. if (nSongPosMS > 0)
  228. {
  229. wchar_t tmp[16];
  230. float time_s = nSongPosMS*0.001f;
  231. int minutes = (int)(time_s/60);
  232. time_s -= minutes*60;
  233. int seconds = (int)time_s;
  234. time_s -= seconds;
  235. int dsec = (int)(time_s*100);
  236. swprintf(tmp, L"%.02f", dsec/100.0f);
  237. swprintf(szSongPos, L"%d:%02d%s", minutes, seconds, tmp+1);
  238. }
  239. }
  240. void GetWinampSongLenAsText(HWND hWndWinamp, wchar_t *szSongLen)
  241. {
  242. // note: size(szSongLen[]) must be at least 64.
  243. szSongLen[0] = 0;
  244. int nSongLenMS = SendMessage(hWndWinamp,WM_USER,1,105)*1000;
  245. if (nSongLenMS > 0)
  246. {
  247. int len_s = nSongLenMS/1000;
  248. int minutes = len_s/60;
  249. int seconds = len_s - minutes*60;
  250. swprintf(szSongLen, L"%d:%02d", minutes, seconds);
  251. }
  252. }
  253. float GetWinampSongPos(HWND hWndWinamp)
  254. {
  255. // returns answer in seconds
  256. return (float)SendMessage(hWndWinamp,WM_USER,0,105)*0.001f;
  257. }
  258. float GetWinampSongLen(HWND hWndWinamp)
  259. {
  260. // returns answer in seconds
  261. return (float)SendMessage(hWndWinamp,WM_USER,1,105);
  262. }
  263. int GetDX9TexFormatBitsPerPixel(D3DFORMAT fmt)
  264. {
  265. switch(fmt)
  266. {
  267. case D3DFMT_DXT1: // 64 bits for each 4x4 pixels = 4 bits per pixel. No Alpha channel.
  268. return 4; // bytes per pixel
  269. case D3DFMT_DXT2: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
  270. case D3DFMT_DXT3: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
  271. case D3DFMT_DXT4: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
  272. case D3DFMT_DXT5: // 128 bits for each 4x4 pixels = 8 bits per pixel. RGB+A.
  273. case D3DFMT_R3G3B2: // 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.
  274. case D3DFMT_A8: // 8-bit alpha only.
  275. case D3DFMT_A8P8: // 8-bit color indexed with 8 bits of alpha.
  276. case D3DFMT_P8: // 8-bit color indexed.
  277. case D3DFMT_L8: // 8-bit luminance only.
  278. case D3DFMT_A4L4: // 8-bit using 4 bits each for alpha and luminance.
  279. return 8;
  280. case D3DFMT_R5G6B5: // 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.
  281. case D3DFMT_X1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color.
  282. case D3DFMT_A1R5G5B5: // 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.
  283. case D3DFMT_A4R4G4B4: // 16-bit ARGB pixel format with 4 bits for each channel.
  284. case D3DFMT_R16F:
  285. case D3DFMT_A8R3G3B2: // 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.
  286. case D3DFMT_X4R4G4B4: // 16-bit RGB pixel format using 4 bits for each color.
  287. case D3DFMT_L16: // 16-bit luminance only.
  288. case D3DFMT_A8L8: // 16-bit using 8 bits each for alpha and luminance.
  289. case D3DFMT_CxV8U8:
  290. case D3DFMT_V8U8:
  291. case D3DFMT_L6V5U5:
  292. return 16;
  293. case D3DFMT_G16R16F:
  294. case D3DFMT_R32F: // 32-bit float format using 32 bits for the red channel.
  295. case D3DFMT_A8R8G8B8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
  296. case D3DFMT_X8R8G8B8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
  297. case D3DFMT_A8B8G8R8: // 32-bit ARGB pixel format with alpha, using 8 bits per channel.
  298. case D3DFMT_X8B8G8R8: // 32-bit RGB pixel format, where 8 bits are reserved for each color.
  299. case D3DFMT_G16R16: // 32-bit pixel format using 16 bits each for green and red.
  300. case D3DFMT_A2R10G10B10: // 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.
  301. case D3DFMT_A2B10G10R10: // 32-bit pixel format using 10 bits for each color and 2 bits for alpha.
  302. case D3DFMT_R8G8B8: // 24-bit RGB pixel format with 8 bits per channel.
  303. case D3DFMT_X8L8V8U8:
  304. case D3DFMT_Q8W8V8U8:
  305. case D3DFMT_V16U16:
  306. return 32;
  307. case D3DFMT_A16B16G16R16F:
  308. case D3DFMT_A16B16G16R16: // 64-bit pixel format using 16 bits for each component.
  309. case D3DFMT_G32R32F: // 64-bit float format using 32 bits for the red channel and 32 bits for the green channel.
  310. return 64;
  311. case D3DFMT_A32B32G32R32F:
  312. return 128;
  313. }
  314. return 32;
  315. }