SWF_Sprites.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #pragma hdrstop
  21. #include "../idlib/precompiled.h"
  22. /*
  23. ========================
  24. idSWFSprite::idSWFSprite
  25. ========================
  26. */
  27. idSWFSprite::idSWFSprite( idSWF * _swf ) :
  28. frameCount( 0 ),
  29. swf( _swf ),
  30. commandBuffer( NULL )
  31. {
  32. }
  33. /*
  34. ========================
  35. idSWFSprite::~idSWFSprite
  36. ========================
  37. */
  38. idSWFSprite::~idSWFSprite() {
  39. Mem_Free( commandBuffer );
  40. }
  41. /*
  42. ========================
  43. idSWF::DefineSprite
  44. ========================
  45. */
  46. void idSWF::DefineSprite( idSWFBitStream & bitstream ) {
  47. uint16 characterID = bitstream.ReadU16();
  48. idSWFDictionaryEntry * entry = AddDictionaryEntry( characterID, SWF_DICT_SPRITE );
  49. if ( entry == NULL ) {
  50. return;
  51. }
  52. entry->sprite->Load( bitstream, false );
  53. }
  54. /*
  55. ========================
  56. idSWFSprite::Load
  57. ========================
  58. */
  59. void idSWFSprite::Load( idSWFBitStream & bitstream, bool parseDictionary ) {
  60. frameCount = bitstream.ReadU16();
  61. // run through the file once, building the dictionary and accumulating control tags
  62. frameOffsets.SetNum( frameCount + 1 );
  63. frameOffsets[0] = 0;
  64. unsigned int currentFrame = 1;
  65. while ( true ) {
  66. uint16 codeAndLength = bitstream.ReadU16();
  67. uint32 recordLength = ( codeAndLength & 0x3F );
  68. if ( recordLength == 0x3F ) {
  69. recordLength = bitstream.ReadU32();
  70. }
  71. idSWFBitStream tagStream( bitstream.ReadData( recordLength ), recordLength, false );
  72. swfTag_t tag = (swfTag_t)( codeAndLength >> 6 );
  73. // ----------------------
  74. // Definition tags
  75. // definition tags are only allowed in the main sprite
  76. // ----------------------
  77. if ( parseDictionary ) {
  78. bool handled = true;
  79. switch ( tag ) {
  80. #define HANDLE_SWF_TAG( x ) case Tag_##x: swf->x( tagStream ); break;
  81. HANDLE_SWF_TAG( JPEGTables );
  82. HANDLE_SWF_TAG( DefineBits );
  83. HANDLE_SWF_TAG( DefineBitsJPEG2 );
  84. HANDLE_SWF_TAG( DefineBitsJPEG3 );
  85. HANDLE_SWF_TAG( DefineBitsLossless );
  86. HANDLE_SWF_TAG( DefineBitsLossless2 );
  87. HANDLE_SWF_TAG( DefineShape );
  88. HANDLE_SWF_TAG( DefineShape2 );
  89. HANDLE_SWF_TAG( DefineShape3 );
  90. HANDLE_SWF_TAG( DefineShape4 );
  91. HANDLE_SWF_TAG( DefineSprite );
  92. HANDLE_SWF_TAG( DefineSound );
  93. //HANDLE_SWF_TAG( DefineMorphShape ); // these don't work right
  94. HANDLE_SWF_TAG( DefineFont2 );
  95. HANDLE_SWF_TAG( DefineFont3 );
  96. HANDLE_SWF_TAG( DefineText );
  97. HANDLE_SWF_TAG( DefineText2 );
  98. HANDLE_SWF_TAG( DefineEditText );
  99. #undef HANDLE_SWF_TAG
  100. default: handled = false;
  101. }
  102. if ( handled ) {
  103. continue;
  104. }
  105. }
  106. // ----------------------
  107. // Control tags
  108. // control tags are stored off in the commands list and processed at run time
  109. // except for a couple really special control tags like "End" and "FrameLabel"
  110. // ----------------------
  111. switch ( tag ) {
  112. case Tag_End:
  113. return;
  114. case Tag_ShowFrame:
  115. frameOffsets[ currentFrame ] = commands.Num();
  116. currentFrame++;
  117. break;
  118. case Tag_FrameLabel: {
  119. swfFrameLabel_t & label = frameLabels.Alloc();
  120. label.frameNum = currentFrame;
  121. label.frameLabel = tagStream.ReadString();
  122. }
  123. break;
  124. case Tag_DoInitAction: {
  125. tagStream.ReadU16();
  126. idSWFBitStream &initaction = doInitActions.Alloc();
  127. initaction.Load( tagStream.ReadData( recordLength - 2 ), recordLength - 2, true );
  128. }
  129. break;
  130. case Tag_DoAction:
  131. case Tag_PlaceObject2:
  132. case Tag_PlaceObject3:
  133. case Tag_RemoveObject2: {
  134. swfSpriteCommand_t & command = commands.Alloc();
  135. command.tag = tag;
  136. command.stream.Load( tagStream.ReadData( recordLength ), recordLength, true );
  137. }
  138. break;
  139. default:
  140. // We don't care, about sprite tags we don't support ... RobA
  141. //idLib::Printf( "Load Sprite: Unhandled tag %s\n", idSWF::GetTagName( tag ) );
  142. break;
  143. }
  144. }
  145. }
  146. /*
  147. ========================
  148. idSWFSprite::Read
  149. ========================
  150. */
  151. void idSWFSprite::Read( idFile * f ) {
  152. int num = 0;
  153. f->ReadBig( frameCount );
  154. f->ReadBig( num ); frameOffsets.SetNum( num );
  155. f->ReadBigArray( frameOffsets.Ptr(), frameOffsets.Num() );
  156. f->ReadBig( num ); frameLabels.SetNum( num );
  157. for ( int i = 0; i < frameLabels.Num(); i++ ) {
  158. f->ReadBig( frameLabels[i].frameNum );
  159. f->ReadString( frameLabels[i].frameLabel );
  160. }
  161. uint32 bufferSize;
  162. f->ReadBig( bufferSize );
  163. commandBuffer = (byte *)Mem_Alloc( bufferSize, TAG_SWF );
  164. f->Read( commandBuffer, bufferSize );
  165. byte * currentBuffer = commandBuffer;
  166. f->ReadBig( num ); commands.SetNum( num );
  167. for ( int i = 0; i < commands.Num(); i++ ) {
  168. uint32 streamLength = 0;
  169. f->ReadBig( commands[i].tag );
  170. f->ReadBig( streamLength );
  171. commands[i].stream.Load( currentBuffer, streamLength, false );
  172. currentBuffer += streamLength;
  173. }
  174. uint32 doInitActionLength = 0;
  175. f->ReadBig( num );
  176. doInitActions.SetNum( num );
  177. for ( int i = 0; i < num; i++ ) {
  178. f->ReadBig( doInitActionLength );
  179. idSWFBitStream &initaction = doInitActions[i];
  180. initaction.Load( currentBuffer, doInitActionLength, true );
  181. currentBuffer += doInitActionLength;
  182. }
  183. }
  184. /*
  185. ========================
  186. idSWFSprite::Write
  187. ========================
  188. */
  189. void idSWFSprite::Write( idFile * f ) {
  190. f->WriteBig( frameCount );
  191. f->WriteBig( frameOffsets.Num() );
  192. f->WriteBigArray( frameOffsets.Ptr(), frameOffsets.Num() );
  193. f->WriteBig( frameLabels.Num() );
  194. for ( int i = 0; i < frameLabels.Num(); i++ ) {
  195. f->WriteBig( frameLabels[i].frameNum );
  196. f->WriteString( frameLabels[i].frameLabel );
  197. }
  198. uint32 totalLength = 0;
  199. for ( int i = 0; i < commands.Num(); i++ ) {
  200. totalLength += commands[i].stream.Length();
  201. }
  202. for (int i = 0; i < doInitActions.Num(); i++ ) {
  203. totalLength += doInitActions[i].Length();
  204. }
  205. f->WriteBig( totalLength );
  206. for ( int i = 0; i < commands.Num(); i++ ) {
  207. f->Write( commands[i].stream.Ptr(), commands[i].stream.Length() );
  208. }
  209. for ( int i = 0; i < doInitActions.Num(); i++ ){
  210. f->Write( doInitActions[i].Ptr(), doInitActions[i].Length() );
  211. }
  212. f->WriteBig( commands.Num() );
  213. for ( int i = 0; i < commands.Num(); i++ ) {
  214. f->WriteBig( commands[i].tag );
  215. f->WriteBig( commands[i].stream.Length() );
  216. }
  217. f->WriteBig( doInitActions.Num() );
  218. for ( int i = 0; i < doInitActions.Num(); i++ ){
  219. f->WriteBig( doInitActions[i].Length() );
  220. }
  221. }