DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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 }