AkFileLocationBase.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #include "BFPlatform.h"
  2. #ifdef BF_WWISE_ENABLED
  3. //////////////////////////////////////////////////////////////////////
  4. //
  5. // AkFileLocationBase.cpp
  6. //
  7. // Basic file location resolving: Uses simple path concatenation logic.
  8. // Exposes basic path functions for convenience.
  9. // For more details on resolving file location, refer to section "File Location" inside
  10. // "Going Further > Overriding Managers > Streaming / Stream Manager > Low-Level I/O"
  11. // of the SDK documentation.
  12. //
  13. // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
  14. //
  15. //////////////////////////////////////////////////////////////////////
  16. #include "Common.h"
  17. #include "AkFileLocationBase.h"
  18. #include <AK/SoundEngine/Common/AkStreamMgrModule.h>
  19. #ifdef AK_WIN
  20. #include <AK/Plugin/AkMP3SourceFactory.h> // For MP3 Codec ID.
  21. #endif
  22. #include <AK/Tools/Common/AkPlatformFuncs.h>
  23. #ifdef AK_SUPPORT_WCHAR
  24. #include <wchar.h>
  25. #endif //AK_SUPPORT_WCHAR
  26. #include <stdio.h>
  27. #include <AK/Tools/Common/AkAssert.h>
  28. #define MAX_NUMBER_STRING_SIZE (10) // 4G
  29. #define ID_TO_STRING_FORMAT_BANK AKTEXT("%u.bnk")
  30. #define ID_TO_STRING_FORMAT_WEM AKTEXT("%u.wem")
  31. #define MAX_EXTENSION_SIZE (4) // .xxx
  32. #define MAX_FILETITLE_SIZE (MAX_NUMBER_STRING_SIZE+MAX_EXTENSION_SIZE+1) // null-terminated
  33. template< class TYPE > inline
  34. const TYPE& AkTemplMax( const TYPE& in_left, const TYPE& in_right )
  35. {
  36. return ( in_left < in_right ) ? in_right : in_left;
  37. }
  38. CAkFileLocationBase::CAkFileLocationBase()
  39. {
  40. m_szBasePath[0] = NULL;
  41. m_szBankPath[0] = NULL;
  42. m_szAudioSrcPath[0] = NULL;
  43. }
  44. CAkFileLocationBase::~CAkFileLocationBase()
  45. {
  46. }
  47. // String overload.
  48. // Returns AK_Success if input flags are supported and the resulting path is not too long.
  49. // Returns AK_Fail otherwise.
  50. AKRESULT CAkFileLocationBase::GetFullFilePath(
  51. const AkOSChar* in_pszFileName, // File name.
  52. AkFileSystemFlags * in_pFlags, // Special flags. Can be NULL.
  53. AkOpenMode in_eOpenMode, // File open mode (read, write, ...).
  54. AkOSChar* out_pszFullFilePath // Full file path.
  55. )
  56. {
  57. if ( !in_pszFileName )
  58. {
  59. AKASSERT( !"Invalid file name" );
  60. return AK_InvalidParameter;
  61. }
  62. // Prepend string path (basic file system logic).
  63. // Compute file name with file system paths.
  64. size_t uiPathSize = AKPLATFORM::OsStrLen( in_pszFileName );
  65. if ( uiPathSize >= AK_MAX_PATH )
  66. {
  67. AKASSERT( !"Input string too large" );
  68. return AK_InvalidParameter;
  69. }
  70. #ifdef AK_WIN
  71. // MP3 files using the MP3 sample code, usually being provided by the gamer will
  72. // not be located in the game path, for these sounds, we are using the Full path
  73. // to access them.
  74. if ( in_pFlags != NULL &&
  75. in_pFlags->uCodecID == AKSOURCEID_MP3 &&
  76. in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC )
  77. {
  78. out_pszFullFilePath[0] = 0;
  79. }
  80. else
  81. #endif
  82. {
  83. AKPLATFORM::SafeStrCpy( out_pszFullFilePath, m_szBasePath, AK_MAX_PATH );
  84. }
  85. if ( in_pFlags
  86. && in_eOpenMode == AK_OpenModeRead )
  87. {
  88. // Add bank path if file is an AK sound bank.
  89. if ( in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC &&
  90. in_pFlags->uCodecID == AKCODECID_BANK )
  91. {
  92. uiPathSize += AKPLATFORM::OsStrLen( m_szBankPath );
  93. if ( uiPathSize >= AK_MAX_PATH )
  94. {
  95. AKASSERT( !"Path is too large" );
  96. return AK_Fail;
  97. }
  98. AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szBankPath, AK_MAX_PATH );
  99. }
  100. // Note: Standard streaming files do not use this overload. On the other hand, streaming external
  101. // sources use it if you use AkExternalSourceInfo::szFile instead of AkExternalSourceInfo::idFile.
  102. // Externally supplied source (see External Sources in SDK doc)
  103. // In this sample, we will assume that the external source file name in_pszFileName
  104. // must be used as is (e.g. "myExternalSourceFile.wem"). If you use the External Source feature
  105. // you should modify this section to handle your FileIDs properly.
  106. /*if (in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL)
  107. {
  108. }*/
  109. // Add language directory name if needed.
  110. if ( in_pFlags->bIsLanguageSpecific )
  111. {
  112. size_t uLanguageStrLen = AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() );
  113. if ( uLanguageStrLen > 0 )
  114. {
  115. uiPathSize += ( uLanguageStrLen + 1 );
  116. if ( uiPathSize >= AK_MAX_PATH )
  117. {
  118. AKASSERT( !"Path is too large" );
  119. return AK_Fail;
  120. }
  121. AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK::StreamMgr::GetCurrentLanguage(), AK_MAX_PATH );
  122. AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK_PATH_SEPARATOR, AK_MAX_PATH );
  123. }
  124. }
  125. }
  126. // Append file title.
  127. uiPathSize += AKPLATFORM::OsStrLen( out_pszFullFilePath );
  128. if ( uiPathSize >= AK_MAX_PATH )
  129. {
  130. AKASSERT( !"File name string too large" );
  131. return AK_Fail;
  132. }
  133. AKPLATFORM::SafeStrCat( out_pszFullFilePath, in_pszFileName, AK_MAX_PATH );
  134. return AK_Success;
  135. }
  136. // ID overload.
  137. // The name of the file will be formatted as ID.ext. This is meant to be used with options
  138. // "Use SoundBank Names" unchecked, and/or "Copy Streamed Files" in the SoundBank Settings.
  139. // For more details, refer to the SoundBank Settings in Wwise Help, and to section "Identifying Banks" inside
  140. // "Sound Engine Integration Walkthrough > Integrate Wwise Elements into Your Game > Integrating Banks >
  141. // Integration Details - Banks > General Information" of the SDK documentation.
  142. // Returns AK_Success if input flags are supported and the resulting path is not too long.
  143. // Returns AK_Fail otherwise.
  144. AKRESULT CAkFileLocationBase::GetFullFilePath(
  145. AkFileID in_fileID, // File ID.
  146. AkFileSystemFlags * in_pFlags, // Special flags.
  147. AkOpenMode /* in_eOpenMode*/, // File open mode (read, write, ...).
  148. AkOSChar * out_pszFullFilePath // Full file path.
  149. )
  150. {
  151. // If the file descriptor could not be found, or if the script-based FS does not exist,
  152. // map file ID to file descriptor (string based) for Audiokinetic IDs.
  153. if ( !in_pFlags ||
  154. !(in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC || in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL))
  155. {
  156. AKASSERT( !"Unhandled file type" );
  157. return AK_Fail;
  158. }
  159. // Compute file name with file system paths.
  160. size_t uiPathSize = AKPLATFORM::OsStrLen( m_szBasePath );
  161. // Copy base path.
  162. AKPLATFORM::SafeStrCpy( out_pszFullFilePath, m_szBasePath, AK_MAX_PATH );
  163. // Concatenate path for AK banks or streamed audio files (everything except banks).
  164. if ( in_pFlags->uCodecID == AKCODECID_BANK )
  165. {
  166. uiPathSize += AKPLATFORM::OsStrLen( m_szBankPath );
  167. if ( uiPathSize >= AK_MAX_PATH )
  168. {
  169. AKASSERT( !"Path is too large" );
  170. return AK_Fail;
  171. }
  172. AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szBankPath, AK_MAX_PATH );
  173. }
  174. else
  175. {
  176. uiPathSize += AKPLATFORM::OsStrLen( m_szAudioSrcPath );
  177. if ( uiPathSize >= AK_MAX_PATH )
  178. {
  179. AKASSERT( !"Path is too large" );
  180. return AK_Fail;
  181. }
  182. AKPLATFORM::SafeStrCat( out_pszFullFilePath, m_szAudioSrcPath, AK_MAX_PATH );
  183. }
  184. // Externally supplied source (see External Sources in SDK doc)
  185. // In this sample, we will assume that the file to load when receiving an external FileID is
  186. // simply the FileID.wem (e.g. "12345.wem"). If you use the External Source feature
  187. // you should modify this section to handle your FileIDs properly.
  188. /*if (in_pFlags->uCompanyID == AKCOMPANYID_AUDIOKINETIC_EXTERNAL)
  189. {
  190. }*/
  191. // Add language directory name if needed.
  192. if ( in_pFlags->bIsLanguageSpecific )
  193. {
  194. size_t uLanguageStrLen = AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() );
  195. if ( uLanguageStrLen > 0 )
  196. {
  197. uiPathSize += ( uLanguageStrLen + 1 );
  198. if ( uiPathSize >= AK_MAX_PATH )
  199. {
  200. AKASSERT( !"Path is too large" );
  201. return AK_Fail;
  202. }
  203. AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK::StreamMgr::GetCurrentLanguage(), AK_MAX_PATH );
  204. AKPLATFORM::SafeStrCat( out_pszFullFilePath, AK_PATH_SEPARATOR, AK_MAX_PATH );
  205. }
  206. }
  207. // Append file title.
  208. if ( ( uiPathSize + MAX_FILETITLE_SIZE ) <= AK_MAX_PATH )
  209. {
  210. AkOSChar * pszTitle = out_pszFullFilePath + uiPathSize;
  211. if ( in_pFlags->uCodecID == AKCODECID_BANK )
  212. AK_OSPRINTF( pszTitle, MAX_FILETITLE_SIZE, ID_TO_STRING_FORMAT_BANK, (unsigned int)in_fileID );
  213. else
  214. AK_OSPRINTF( pszTitle, MAX_FILETITLE_SIZE, ID_TO_STRING_FORMAT_WEM, (unsigned int)in_fileID );
  215. }
  216. else
  217. {
  218. AKASSERT( !"String buffer too small" );
  219. return AK_Fail;
  220. }
  221. return AK_Success;
  222. }
  223. AKRESULT CAkFileLocationBase::SetBasePath(
  224. const AkOSChar* in_pszBasePath
  225. )
  226. {
  227. if ( AKPLATFORM::OsStrLen( in_pszBasePath ) + AkTemplMax( AKPLATFORM::OsStrLen( m_szBankPath ), AKPLATFORM::OsStrLen( m_szAudioSrcPath ) ) + AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() ) + 1 >= AK_MAX_PATH )
  228. {
  229. return AK_InvalidParameter;
  230. }
  231. AKPLATFORM::SafeStrCpy( m_szBasePath, in_pszBasePath, AK_MAX_PATH );
  232. return AK_Success;
  233. }
  234. AKRESULT CAkFileLocationBase::SetBankPath(
  235. const AkOSChar* in_pszBankPath
  236. )
  237. {
  238. if ( AKPLATFORM::OsStrLen( m_szBasePath ) + AkTemplMax( AKPLATFORM::OsStrLen( in_pszBankPath ), AKPLATFORM::OsStrLen( m_szAudioSrcPath ) ) + AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() ) + 1 >= AK_MAX_PATH )
  239. {
  240. return AK_InvalidParameter;
  241. }
  242. AKPLATFORM::SafeStrCpy( m_szBankPath, in_pszBankPath, AK_MAX_PATH );
  243. return AK_Success;
  244. }
  245. AKRESULT CAkFileLocationBase::SetAudioSrcPath(
  246. const AkOSChar* in_pszAudioSrcPath
  247. )
  248. {
  249. if ( AKPLATFORM::OsStrLen( m_szBasePath ) + AkTemplMax( AKPLATFORM::OsStrLen( m_szBankPath ), AKPLATFORM::OsStrLen( in_pszAudioSrcPath ) ) + AKPLATFORM::OsStrLen( AK::StreamMgr::GetCurrentLanguage() ) + 1 >= AK_MAX_PATH )
  250. {
  251. return AK_InvalidParameter;
  252. }
  253. AKPLATFORM::SafeStrCpy( m_szAudioSrcPath, in_pszAudioSrcPath, AK_MAX_PATH );
  254. return AK_Success;
  255. }
  256. #endif