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