SWF_PlaceObject.cpp (8254B)
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 int c_PlaceObject2; 32 int c_PlaceObject3; 33 34 #define PlaceFlagHasClipActions BIT( 7 ) 35 #define PlaceFlagHasClipDepth BIT( 6 ) 36 #define PlaceFlagHasName BIT( 5 ) 37 #define PlaceFlagHasRatio BIT( 4 ) 38 #define PlaceFlagHasColorTransform BIT( 3 ) 39 #define PlaceFlagHasMatrix BIT( 2 ) 40 #define PlaceFlagHasCharacter BIT( 1 ) 41 #define PlaceFlagMove BIT( 0 ) 42 43 #define PlaceFlagPad0 BIT( 7 ) 44 #define PlaceFlagPad1 BIT( 6 ) 45 #define PlaceFlagPad2 BIT( 5 ) 46 #define PlaceFlagHasImage BIT( 4 ) 47 #define PlaceFlagHasClassName BIT( 3 ) 48 #define PlaceFlagCacheAsBitmap BIT( 2 ) 49 #define PlaceFlagHasBlendMode BIT( 1 ) 50 #define PlaceFlagHasFilterList BIT( 0 ) 51 52 /* 53 ======================== 54 idSWFSpriteInstance::PlaceObject2 55 ======================== 56 */ 57 void idSWFSpriteInstance::PlaceObject2( idSWFBitStream & bitstream ) { 58 c_PlaceObject2++; 59 60 uint64 flags = bitstream.ReadU8(); 61 int depth = bitstream.ReadU16(); 62 63 int characterID = -1; 64 if ( ( flags & PlaceFlagHasCharacter ) != 0 ) { 65 characterID = bitstream.ReadU16(); 66 } 67 68 swfDisplayEntry_t * display = NULL; 69 70 if ( ( flags & PlaceFlagMove ) != 0 ) { 71 // modify an existing entry 72 display = FindDisplayEntry( depth ); 73 if ( display == NULL ) { 74 idLib::Warning( "PlaceObject2: trying to modify entry %d, which doesn't exist", depth ); 75 return; 76 } 77 if ( characterID >= 0 ) { 78 // We are very picky about what kind of objects can change characters 79 // Shapes can become other shapes, but sprites can never change 80 if ( display->spriteInstance || display->textInstance ) { 81 idLib::Warning( "PlaceObject2: Trying to change the character of a sprite after it's been created" ); 82 return; 83 } 84 idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID ); 85 if ( dictEntry != NULL ) { 86 if ( dictEntry->type == SWF_DICT_SPRITE || dictEntry->type == SWF_DICT_EDITTEXT ) { 87 idLib::Warning( "PlaceObject2: Trying to change the character of a shape to a sprite" ); 88 return; 89 } 90 } 91 display->characterID = characterID; 92 } 93 } else { 94 if ( characterID < 0 ) { 95 idLib::Warning( "PlaceObject2: Trying to create a new object without a character" ); 96 return; 97 } 98 // create a new entry 99 display = AddDisplayEntry( depth, characterID ); 100 if ( display == NULL ) { 101 idLib::Warning( "PlaceObject2: trying to create a new entry at %d, but an item already exists there", depth ); 102 return; 103 } 104 } 105 if ( ( flags & PlaceFlagHasMatrix ) != 0 ) { 106 bitstream.ReadMatrix( display->matrix ); 107 } 108 if ( ( flags & PlaceFlagHasColorTransform ) != 0 ) { 109 bitstream.ReadColorXFormRGBA( display->cxf ); 110 } 111 if ( ( flags & PlaceFlagHasRatio ) != 0 ) { 112 display->ratio = bitstream.ReadU16() * ( 1.0f / 65535.0f ); 113 } 114 if ( ( flags & PlaceFlagHasName ) != 0 ) { 115 idStr name = bitstream.ReadString(); 116 if ( display->spriteInstance ) { 117 display->spriteInstance->name = name; 118 scriptObject->Set( name, display->spriteInstance->GetScriptObject() ); 119 } else if ( display->textInstance ) { 120 scriptObject->Set( name, display->textInstance->GetScriptObject() ); 121 } 122 } 123 if ( ( flags & PlaceFlagHasClipDepth ) != 0 ) { 124 display->clipDepth = bitstream.ReadU16(); 125 } 126 if ( ( flags & PlaceFlagHasClipActions ) != 0 ) { 127 // FIXME: clip actions 128 } 129 } 130 131 /* 132 ======================== 133 idSWFSpriteInstance::PlaceObject3 134 ======================== 135 */ 136 void idSWFSpriteInstance::PlaceObject3( idSWFBitStream & bitstream ) { 137 c_PlaceObject3++; 138 139 uint64 flags1 = bitstream.ReadU8(); 140 uint64 flags2 = bitstream.ReadU8(); 141 uint16 depth = bitstream.ReadU16(); 142 143 if ( ( flags2 & PlaceFlagHasClassName ) != 0 || ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) { 144 bitstream.ReadString(); // ignored 145 } 146 147 int characterID = -1; 148 if ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) { 149 characterID = bitstream.ReadU16(); 150 } 151 152 swfDisplayEntry_t * display = NULL; 153 154 if ( ( flags1 & PlaceFlagMove ) != 0 ) { 155 // modify an existing entry 156 display = FindDisplayEntry( depth ); 157 if ( display == NULL ) { 158 idLib::Warning( "PlaceObject3: trying to modify entry %d, which doesn't exist", depth ); 159 return; 160 } 161 if ( characterID >= 0 ) { 162 // We are very picky about what kind of objects can change characters 163 // Shapes can become other shapes, but sprites can never change 164 if ( display->spriteInstance || display->textInstance ) { 165 idLib::Warning( "PlaceObject3: Trying to change the character of a sprite after it's been created" ); 166 return; 167 } 168 idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID ); 169 if ( dictEntry != NULL ) { 170 if ( dictEntry->type == SWF_DICT_SPRITE || dictEntry->type == SWF_DICT_EDITTEXT ) { 171 idLib::Warning( "PlaceObject3: Trying to change the character of a shape to a sprite" ); 172 return; 173 } 174 } 175 display->characterID = characterID; 176 } 177 } else { 178 if ( characterID < 0 ) { 179 idLib::Warning( "PlaceObject3: Trying to create a new object without a character" ); 180 return; 181 } 182 // create a new entry 183 display = AddDisplayEntry( depth, characterID ); 184 if ( display == NULL ) { 185 idLib::Warning( "PlaceObject3: trying to create a new entry at %d, but an item already exists there", depth ); 186 return; 187 } 188 } 189 if ( ( flags1 & PlaceFlagHasMatrix ) != 0 ) { 190 bitstream.ReadMatrix( display->matrix ); 191 } 192 if ( ( flags1 & PlaceFlagHasColorTransform ) != 0 ) { 193 bitstream.ReadColorXFormRGBA( display->cxf ); 194 } 195 if ( ( flags1 & PlaceFlagHasRatio ) != 0 ) { 196 display->ratio = bitstream.ReadU16() * ( 1.0f / 65535.0f ); 197 } 198 if ( ( flags1 & PlaceFlagHasName ) != 0 ) { 199 idStr name = bitstream.ReadString(); 200 if ( display->spriteInstance ) { 201 display->spriteInstance->name = name; 202 scriptObject->Set( name, display->spriteInstance->GetScriptObject() ); 203 } else if ( display->textInstance ) { 204 scriptObject->Set( name, display->textInstance->GetScriptObject() ); 205 } 206 } 207 if ( ( flags1 & PlaceFlagHasClipDepth ) != 0 ) { 208 display->clipDepth = bitstream.ReadU16(); 209 } 210 if ( ( flags2 & PlaceFlagHasFilterList ) != 0 ) { 211 // we don't support filters and because the filter list is variable length we 212 // can't support anything after the filter list either (blend modes and clip actions) 213 idLib::Warning( "PlaceObject3: has filters" ); 214 return; 215 } 216 if ( ( flags2 & PlaceFlagHasBlendMode ) != 0 ) { 217 display->blendMode = bitstream.ReadU8(); 218 } 219 if ( ( flags1 & PlaceFlagHasClipActions ) != 0 ) { 220 // FIXME: 221 } 222 } 223 224 /* 225 ======================== 226 idSWFSpriteInstance::RemoveObject2 227 ======================== 228 */ 229 void idSWFSpriteInstance::RemoveObject2( idSWFBitStream & bitstream ) { 230 RemoveDisplayEntry( bitstream.ReadU16() ); 231 }