SWF_PlaceObject.cpp 8.1 KB

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