From c9dc7aaf164611b07773405c00b6237d3e89273f Mon Sep 17 00:00:00 2001 From: HarrievG Date: Sun, 19 Feb 2023 02:17:27 +0100 Subject: [PATCH 01/20] Initial SWF AS3.0 support --- neo/swf/SWF.h | 18 +- neo/swf/SWF_Abc.cpp | 739 ++++++++++++++++++++++++++++++ neo/swf/SWF_Abc.h | 229 +++++++++ neo/swf/SWF_Bitstream.h | 14 + neo/swf/SWF_Dictionary.cpp | 11 +- neo/swf/SWF_Enums.h | 48 +- neo/swf/SWF_EventDispatcher.cpp | 158 +++++++ neo/swf/SWF_EventDispatcher.h | 63 +++ neo/swf/SWF_Events.cpp | 180 +++++++- neo/swf/SWF_Interpreter.cpp | 789 ++++++++++++++++++++++++++++++++ neo/swf/SWF_Load.cpp | 15 +- neo/swf/SWF_Main.cpp | 139 +++++- neo/swf/SWF_PlaceObject.cpp | 15 +- neo/swf/SWF_ScriptFunction.cpp | 33 +- neo/swf/SWF_ScriptFunction.h | 29 +- neo/swf/SWF_ScriptObject.cpp | 31 +- neo/swf/SWF_ScriptObject.h | 29 +- neo/swf/SWF_ScriptVar.cpp | 1 + neo/swf/SWF_ScriptVar.h | 49 +- neo/swf/SWF_ShapeParser.cpp | 178 ++++++- neo/swf/SWF_ShapeParser.h | 11 +- neo/swf/SWF_SpriteInstance.cpp | 202 ++++++-- neo/swf/SWF_SpriteInstance.h | 5 + neo/swf/SWF_Sprites.cpp | 2 + neo/swf/SWF_TextInstance.cpp | 74 +++ neo/swf/SWF_TextInstance.h | 10 +- neo/swf/SWF_Types.h | 3 + neo/swf/opcodes.tbl | 297 ++++++++++++ 28 files changed, 3202 insertions(+), 170 deletions(-) create mode 100644 neo/swf/SWF_Abc.cpp create mode 100644 neo/swf/SWF_Abc.h create mode 100644 neo/swf/SWF_EventDispatcher.cpp create mode 100644 neo/swf/SWF_EventDispatcher.h create mode 100644 neo/swf/SWF_Interpreter.cpp create mode 100644 neo/swf/opcodes.tbl diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index 260f84c096..00d171e84f 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -41,8 +41,10 @@ If you have questions concerning this license or the applicable additional terms #include "SWF_ParmList.h" #include "SWF_ScriptFunction.h" #include "SWF_SpriteInstance.h" +#include "SWF_EventDispatcher.h" #include "SWF_ShapeParser.h" #include "SWF_TextInstance.h" +#include "SWF_Abc.h" class idSWFDictionaryEntry { @@ -65,6 +67,9 @@ class idSWFDictionaryEntry // the compressed images are normalize to reduce compression artifacts, // color must be scaled down by this idVec4 channelScale; + idSWFScriptVar scriptClass; + bool resolved; + idStrPtr name; }; struct purgableSwfImage_t @@ -215,6 +220,7 @@ class idSWF idSWFScriptObject* HitTest( idSWFSpriteInstance* spriteInstance, const swfRenderState_t& renderState, int x, int y, idSWFScriptObject* parentObject ); + SWF_AbcFile abcFile; private: idStr filename; ID_TIME_T timestamp; @@ -289,6 +295,7 @@ class idSWF SWF_NATIVE_FUNCTION_SWF_DECLARE( getCVarInteger ); SWF_NATIVE_FUNCTION_SWF_DECLARE( setCVarInteger ); SWF_NATIVE_FUNCTION_SWF_DECLARE( strReplace ); + SWF_NATIVE_FUNCTION_SWF_DECLARE( trace ); SWF_NATIVE_FUNCTION_SWF_DECLARE( acos ); SWF_NATIVE_FUNCTION_SWF_DECLARE( cos ); @@ -307,7 +314,8 @@ class idSWF SWF_NATIVE_VAR_DECLARE_NESTED( blackbars, idSWF ); SWF_NATIVE_VAR_DECLARE_NESTED( crop, idSWF ); - class idSWFScriptFunction_Object : public idSWFScriptFunction + class idSWFScriptFunction_Object; + SWF_NATIVE_VAR_DECLARE_NESTED_READONLY( Object, idSWFScriptFunction_Object, Call( object, idSWFParmList() ) ); class idSWFScriptFunction_Object : public idSWFScriptFunction { public: idSWFScriptVar Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) @@ -516,6 +524,12 @@ class idSWF // SWF_Zlib.cpp //---------------------------------- bool Inflate( const byte* input, int inputSize, byte* output, int outputSize ); + //---------------------------------- + // SWF_Abc.cpp + //---------------------------------- + void DoABC( idSWFBitStream & bitstream ) ; + void SymbolClass( idSWFBitStream & bitstream ) ; + // RB begin bool Deflate( const byte* input, int inputSize, byte* output, int& outputSize ); // RB end @@ -531,6 +545,8 @@ class idSWF static const char* GetTagName( swfTag_t tag ); static const char* GetActionName( swfAction_t action ); + void CreateAbcObjects( idSWFScriptObject *globals ); + SWF_SymbolClass symbolClasses; }; #endif // !__SWF_H__ diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp new file mode 100644 index 0000000000..385aff23f7 --- /dev/null +++ b/neo/swf/SWF_Abc.cpp @@ -0,0 +1,739 @@ + +/* +=========================================================================== + +Copyright (C) 2022 HvanGinneken + +=========================================================================== +*/ + +//.AS test +//trace( "hello" ) +//trace( "world" ) +//var clickCount = 0; +//function playAnimation( event:MouseEvent ) :void { +// clickCount++; +// trace( text1.text ) +// text1.text = "clicked me " + clickCount; +//} +//// Register the function as a listener with the button. +//addEventListener( MouseEvent.CLICK, playAnimation ); + +#include "precompiled.h" +#pragma hdrstop + +#include "SWF_Abc.h" + +idCVar swf_abc_verbose( "swf_abc_verbose", "1", CVAR_INTEGER, "1 : writes out all abc data read \n 2 : print bytecode "); + +#pragma warning( disable: 4189 ) // local variable is initialized but not referenced + +void trace( const char *fmt, ... ) { + if ( swf_abc_verbose.GetInteger() == 1 ) + { + //common->PrintPrefix("[SWF]"); + va_list argptr; + va_start( argptr, fmt ); + common->VPrintf( fmt, argptr ); + va_end( argptr ); + //common->PrintPrefix(""); + } +} + +#define toString(x) asString(x,constant_pool) + +idStr SWF_AbcFile::asString( swfConstantKind_t kind, swfConstant_pool_info &constant_pool ) { + idStr type; +#define switchTrace( n ) case n: type = #n;break; + switch ( kind ) { + switchTrace( unused_0x00 ); + switchTrace( Utf8 ); + switchTrace( Int ); + switchTrace( UInt ); + switchTrace( PrivateNs ); + switchTrace( Double ); + switchTrace( Qname ); + switchTrace( Namespace ); + switchTrace( False ); + switchTrace( True ); + switchTrace( Null ); + switchTrace( QnameA ); + switchTrace( RTQname ); + switchTrace( RTQnameA ); + switchTrace( RTQnameL ); + switchTrace( RTQnameLA ); + switchTrace( Multiname ); + switchTrace( MultinameA ); + switchTrace( MultinameL ); + switchTrace( MultinameLA ); + switchTrace( PackageNamespace ); + switchTrace( PackageInternalNs ); + switchTrace( ProtectedNamespace ); + switchTrace( ExplicitNamespace ); + switchTrace( StaticProtectedNs ); + } + return type; +#undef switchTrace +} + +idStr SWF_AbcFile::asString( swfMultiname *mn, swfConstant_pool_info &constant_pool,bool prefix /*= true*/ ) +{ + idStr ret; + if (prefix) ret += toString( mn->type ); + switch ( mn->type ) { + case RTQnameL: + case RTQnameLA: + ret += "null::null"; + break; + case Qname: + case QnameA: + ret += " "; ret += *constant_pool.namespaceNames[mn->index]; + if (mn->index!=1) ret += "."; + ret += constant_pool.utf8Strings[mn->nameIndex]; + break; + + case RTQname: + case RTQnameA: + ret+= " ";ret+=constant_pool.utf8Strings[mn->nameIndex]; + break; + + case TypeName: + case Multiname: + case MultinameA: + ret += " "; ret += asString(&constant_pool.multinameInfos[mn->index],constant_pool); + ret += "."; ret += constant_pool.utf8Strings[mn->nameIndex]; + break; + + case MultinameL: + case MultinameLA: + ret += " "; for ( auto * str : constant_pool.namespaceSets[mn->index] ){ ret += *str; ret+="."; }; + break; + case unused_0x00: + ret += " unused_0x00"; + break; + default: + common->FatalError( "Invalid Multiname type" ); + break; + } + + return ret; +} + +void SWF_AbcFile::traceMN( const char *name, swfMultiname *mn, swfConstant_pool_info &constant_pool ) +{ + idStr type = asString(mn,constant_pool ); + trace( "%s %s \n",name,type.c_str() ); +} + +void SWF_AbcFile::traceConstantPool( swfConstant_pool_info &constant_pool ) +{ + int cnt = 0; + + trace("^8========================================================\n" ); + trace(" constant pool \n" ); + trace("^8========================================================\n" ); + + trace("^8integers : ^7%i\n", constant_pool.integers.Num() ); + for (auto& t : constant_pool.integers) + trace( "^8[^7%i^8]\t ^7%i \n", cnt++, t ); + trace( "^8uIntegers ^7: %i\n", constant_pool.uIntegers.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.uIntegers ) + trace( "^8[^7%i^8]\t ^7%i \n",cnt++, (int)t ); + trace( "^8doubles ^7: %i\n", constant_pool.doubles.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.doubles ) + trace( "^8[^7%i^8]\t ^7%f \n",cnt++, ( float ) t ); + trace( "^8utf8Strings ^7: %i\n", constant_pool.utf8Strings.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.utf8Strings ) + trace( "^8[^7%i^8]\t ^7%s \n",cnt++, t.c_str( ) ); + trace( "^8namespaceNames ^7: %i\n", constant_pool.namespaceNames.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.namespaceNames ) + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t->c_str( ) ); + + trace( "^8namespaceSets ^7: %i\n", constant_pool.namespaceSets.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.namespaceSets ) + { + for ( auto &ts : t ) + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, ts->c_str( ) ); + } + + trace( "^8multinameInfos ^7: %i\n", constant_pool.multinameInfos.Num( ) ); cnt = 0; + for ( auto &t : constant_pool.multinameInfos ) + { + idStr pre="^8[^7";pre+=idStr(cnt++);pre+="^8]^7\t"; + traceMN(pre.c_str(),&t,constant_pool); + } + + trace("^8========================================================\n" ); +} + +void ReadMultiName( idSWFBitStream & bitstream ,swfMultiname & target ) +{ + target.type = (swfConstantKind_t )bitstream.ReadU8(); + target.index = 0; + target.nameIndex = 0; + switch ( target.type ) + { + case RTQnameL: + case RTQnameLA: + //0,0 + break; + case Qname: + case QnameA: + target.index = bitstream.ReadEncodedU32(); + target.nameIndex = bitstream.ReadEncodedU32(); + break; + + case RTQname: + case RTQnameA: + target.nameIndex = bitstream.ReadEncodedU32(); + break; + + case TypeName: + target.nameIndex = bitstream.ReadEncodedU32( ); + target.nameIndexT =bitstream.ReadEncodedU32( ); + target.indexT = bitstream.ReadEncoded( ); + break; + case Multiname: + case MultinameA: + target.nameIndex = bitstream.ReadEncodedU32( ); + target.index = bitstream.ReadEncodedU32( ); + break; + + case MultinameL: + case MultinameLA: + target.index = bitstream.ReadEncodedU32( ); + break; + default: + common->FatalError("Invalid Multiname type"); + break; + } +} + +void ReadConstantPoolInfo( idSWFBitStream & bitstream , swfConstant_pool_info & target ) +{ + /*cpool_info{}*/ + uint32 int_count = bitstream.ReadEncodedU32( ) ; + target.integers.Alloc( ) = 0; + for ( uint i = 1; i < int_count; i++ ) + target.integers.Alloc( ) = bitstream.ReadEncoded( ); + + uint32 uint_count = bitstream.ReadEncodedU32( ); + target.uIntegers.Alloc( ) = 0; + for ( uint i = 1; i < uint_count; i++ ) + target.uIntegers.Alloc( ) = bitstream.ReadEncodedU32( ); + + uint32 double_count = bitstream.ReadEncodedU32( ); + target.doubles.Alloc( ) = 0.0; + for ( uint i = 1; i < double_count; i++ ) + target.doubles.Alloc( ) = bitstream.ReadDouble( ); + + uint32 string_count = bitstream.ReadEncodedU32( ); + target.utf8Strings.Alloc( ).Append("*"); + for ( uint i = 1; i < string_count; i++ ) { + uint32 str_len = bitstream.ReadEncodedU32( ); + target.utf8Strings.Alloc( ).Append( ( char * ) bitstream.ReadData( str_len ),str_len ); + } + + uint32 namespace_count = bitstream.ReadEncodedU32( ); + target.namespaceNames.Alloc( ) = &target.utf8Strings[0]; + for ( uint i = 1; i < namespace_count; i++ ) { + target.namespaceKinds.Alloc() = (swfConstantKind_t)bitstream.ReadU8(); + uint32 str_idx = bitstream.ReadEncodedU32( ); + target.namespaceNames.Alloc( ) = &target.utf8Strings[(int)str_idx]; + } + + uint32 namespace_set_count = bitstream.ReadEncodedU32( ); + target.namespaceSets.Alloc( ).Alloc() = target.namespaceNames[0]; + for ( uint i = 1; i < namespace_set_count; i++ ) { + uint32 count = bitstream.ReadEncodedU32( ); + auto & newSet = target.namespaceSets.Alloc(); + for (uint j = 0; j < count; j++) + { + uint32 idx = bitstream.ReadEncodedU32( ); + newSet.Alloc() = target.namespaceNames[(int)idx]; + } + } + + uint32 multiname_count = bitstream.ReadEncodedU32( ); + auto & empty = target.multinameInfos.Alloc( ); + empty.index = 0; + empty.nameIndex = 0; + empty.type = unused_0x00; + for ( uint i = 1; i < multiname_count; i++ ) { + auto &newMn = target.multinameInfos.Alloc( ); + ReadMultiName(bitstream,newMn); + } +} + +void SWF_AbcFile::ReadOptionInfo( idSWFBitStream &bitstream, swfOption_info &newOption ) +{ + newOption.option_count = bitstream.ReadEncodedU32( ); + for ( uint i = 0; i < newOption.option_count; i++ ) { + auto &newItem = newOption.options.Alloc( ); + newItem.val = bitstream.ReadEncodedU32( ); + newItem.kind = constant_pool.namespaceKinds[bitstream.ReadEncodedU32( )]; + } +} + +void SWF_AbcFile::ReadMetaDataInfo ( idSWFBitStream & bitstream , swfMetadata_info & newMetadata ) +{ + newMetadata.name = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; + uint32 item_count = bitstream.ReadEncodedU32(); + for (uint i = 0; i < item_count; i++ ) { + auto & newItem = newMetadata.items.Alloc(); + newItem.key = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; + newItem.value = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; + } +} + +void SWF_AbcFile::ReadTraitData( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ) +{ + swfTraits_info::Type kind = (swfTraits_info::Type)((newTraitsData.kind << 4) >> 4); // snip upper half, lower 4 bits should remain. + uint8 attrib = (newTraitsData.kind >> 4); // snip lower half, upper 4 bits should remain. + + switch ( kind ) { + case swfTraits_info::Trait_Slot: + case swfTraits_info::Trait_Const: { + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_slot ) ,TAG_SWF ); + swfTrait_slot &slot = *(( swfTrait_slot * )( newTraitsData.data )); + slot.slot_id = bitstream.ReadEncodedU32(); + slot.type_name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + slot.vindex = bitstream.ReadEncodedU32(); + if ( slot.vindex != 0 ) + slot.vkind = bitstream.ReadU8(); + }break; + case swfTraits_info::Trait_Method: + case swfTraits_info::Trait_Getter: + case swfTraits_info::Trait_Setter:{ + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_method ), TAG_SWF); + swfTrait_method &method = *( swfTrait_method * )( newTraitsData.data ); + method.disp_id = bitstream.ReadEncodedU32( ); + method.method = &methods[bitstream.ReadEncodedU32( )]; + }break; + case swfTraits_info::Trait_Class:{ + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ), TAG_SWF); + swfTrait_class &tclass = *( swfTrait_class * )( newTraitsData.data ); + tclass.slot_id = bitstream.ReadEncodedU32( ); + tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + }break; + case swfTraits_info::Trait_Function:{ + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ), TAG_SWF); + swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); + func.slot_id = bitstream.ReadEncodedU32( ); + func.func = &methods[bitstream.ReadEncodedU32( )]; + }break; + + default: + common->FatalError("Unknown trait data"); + break; + } +} + +struct idSWFScriptObject::swfNamedVar_t ; + +template<> +idSWFScriptObject::swfNamedVar_t * SWF_AbcFile::GetTrait( const swfTraits_info &trait,idSWFScriptObject * globals ) { + swfTraits_info::Type kind = ( swfTraits_info::Type ) ( ( trait.kind << 4 ) >> 4 ); // snip upper half, lower 4 bits should remain. + uint8 attrib = ( trait.kind >> 4 ); // snip lower half, upper 4 bits should remain. + + //idSWFScriptObject* newObj = new idSWFScriptObject(); + idSWFScriptObject::swfNamedVar_t * newVar = new idSWFScriptObject::swfNamedVar_t(); + newVar->value.traitsInfo = &trait; + switch ( kind ) { + case swfTraits_info::Trait_Slot: + case swfTraits_info::Trait_Const: + { //member variable. + swfTrait_slot &slot = *( ( swfTrait_slot * ) ( trait.data ) ); + newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + //if ( slot.slot_id ) + //{ + // newVar = newObj->GetVariable(slot.slot_id,true); + // newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + //}else + // newVar = newObj->GetVariable(constant_pool.utf8Strings[trait.name->nameIndex].c_str(),true); + + if ( slot.vindex != 0 ) + switch ( slot.vkind ) { + case Utf8: + newVar->value.SetString(constant_pool.utf8Strings[slot.vindex]); + break; + case Int: + newVar->value.SetInteger(constant_pool.integers[slot.vindex]); + break; + case UInt: + newVar->value.SetInteger((int32)(constant_pool.uIntegers[slot.vindex])); + break; + case Double: // crap. + newVar->value.SetFloat((float)(constant_pool.doubles[slot.vindex])); + break; + case Qname: + { + + } + case Namespace: + newVar->value.SetString(*constant_pool.namespaceNames[slot.vindex]); + break; + case Multiname: + break; + case False: + newVar->value.SetBool(false); + break; + case True: + newVar->value.SetBool(true); + break; + case Null: + newVar->value.SetUndefined(); + break; + case QnameA: + { + idStr &typeName = constant_pool.utf8Strings[slot.vindex]; + if ( globals->HasProperty( typeName.c_str( ) ) ) + newVar->value.SetObject( globals->GetObject( typeName ) ); + else + newVar->value.SetUndefined(); + break; + } + break; + case MultinameA: + break; + case RTQname: + break; + case RTQnameA: + break; + case RTQnameL: + break; + case RTQnameLA: + break; + case NamespaceSet: + break; + case PackageNamespace: + break; + case PackageInternalNs: + break; + case ProtectedNamespace: + break; + case ExplicitNamespace: + break; + case StaticProtectedNs: + break; + case MultinameL: + break; + case MultinameLA: + break; + case TypeName: + break; + default: + break; + } + else + { + idStr &typeName = constant_pool.utf8Strings[slot.type_name->nameIndex]; + if ( globals->HasProperty( typeName.c_str( ) ) ) + { + auto * newobj = idSWFScriptObject::Alloc(); + newobj->SetPrototype( globals->GetObject( typeName.c_str() )); + newVar->value.SetObject( newobj ); + } + else + newVar->value.SetUndefined(); + break; + } + + return newVar; + }break; + case swfTraits_info::Trait_Method: + case swfTraits_info::Trait_Getter: + case swfTraits_info::Trait_Setter: + { + newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + swfTrait_method &method = *( ( swfTrait_method * ) ( trait.data ) ); + + idStrPtr name = method.method->name; + idStr owner; + //string method owner + //common->FatalError("This is wrong. now dont keep using the debug info but start resolving it properly!!!!"); + //check frame scripts! + int slashPos = name->Find("/"); + if (slashPos != -1) + owner = idStr(name->c_str(),0,slashPos); + + slashPos = owner.Find( ":" ); + if ( slashPos != -1 ) + owner = idStr( owner.c_str( ), slashPos+1, owner.Length() ); + + if ( globals->HasProperty( owner.c_str() ) ) { + idSWFScriptFunction_Script *func = idSWFScriptFunction_Script::Alloc( ); + func->SetAbcFile( this ); + func->SetData( method.method ); + newVar->value= idSWFScriptVar( func ) ; + } else + newVar->value.SetUndefined( ); + break; + + }break; + case swfTraits_info::Trait_Class: + { + int a = 0; + //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ) ); + //swfTrait_class &tclass = *( swfTrait_class * ) ( newTraitsData.data ); + //tclass.slot_id = bitstream.ReadEncodedU32( ); + //tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + }break; + case swfTraits_info::Trait_Function: + { + int a = 0; + //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ) ); + //swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); + //func.slot_id = bitstream.ReadEncodedU32( ); + //func.func = &methods[bitstream.ReadEncodedU32( )]; + }break; + + default: + common->FatalError( "Unknown trait data" ); + break; + } + + return newVar; +} + +void SWF_AbcFile::ReadTraitsInfo( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ) +{ + newTraitsData.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + //The kind field contains two four-bit fields. The lower four bits determine the kind of this trait. The + // upper four bits comprise a bit vector providing attributes of the trait. See the following tables and + // sections for full descriptions. + + newTraitsData.kind = bitstream.ReadU8(); + ReadTraitData( bitstream, newTraitsData ); + uint8 attrib = ( newTraitsData.kind >> 4 ); // snip lower half, upper 4 bits should remain. + if ((attrib & swfTraits_info::Attrib::Metadata) != 0 ) { + uint32 meta_count = bitstream.ReadEncodedU32(); + for (uint i = 0 ; i < meta_count; i++) { + newTraitsData.metadatas.Alloc() = &metadatas[bitstream.ReadEncodedU32()]; + //fix this. + } + } +} + +void SWF_AbcFile::ReadClassInfo( idSWFBitStream &bitstream, swfClass_info &newClassData ) +{ + newClassData.cinit = &methods[bitstream.ReadEncodedU32()]; + uint32 trait_count = bitstream.ReadEncodedU32(); + newClassData.traits.AssureSize(trait_count); + for ( uint i = 0; i < trait_count; i++ ) { + ReadTraitsInfo( bitstream, newClassData.traits[i] ); + } + +} + +//The last entry in that array is the entry point for the ABC file; that is, the last entry�s +//initialization method contains the first bytecode that�s run when the ABC file is executed. +void SWF_AbcFile::ReadScriptInfo( idSWFBitStream &bitstream, swfScript_info &newScriptData ) +{ + uint32 init = bitstream.ReadEncodedU32( ); + uint32 trait_count = bitstream.ReadEncodedU32( ); + newScriptData.init = &methods[init]; + trace("%s \n",newScriptData.init->name->c_str()); + newScriptData.traits.AssureSize(trait_count); + for ( uint i = 0; i < trait_count; i++ ) { + ReadTraitsInfo( bitstream, newScriptData.traits[i] ); + } +} + +void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream &bitstream, swfMethod_body_info &newMethodBody ) +{ + newMethodBody.method = &methods[bitstream.ReadEncodedU32()]; + assert(newMethodBody.method->body==nullptr); + newMethodBody.method->body = &newMethodBody; + + newMethodBody.max_stack = bitstream.ReadEncodedU32(); + newMethodBody.localCount = bitstream.ReadEncodedU32(); + newMethodBody.initScopeDepth = bitstream.ReadEncodedU32(); + newMethodBody.maxScopeDepth = bitstream.ReadEncodedU32(); + newMethodBody.codeLength = bitstream.ReadEncodedU32(); + newMethodBody.code.Load(bitstream.ReadData(newMethodBody.codeLength),newMethodBody.codeLength,true);// ( byte * ) Mem_ClearedAlloc( sizeof( byte ) * newMethodBody.codeLength ); + extern void swf_PrintStream(SWF_AbcFile * file ,idSWFBitStream & bitstream); + if ( swf_abc_verbose.GetInteger( ) == 2 ) + { + common->Printf("============================\n"); + common->Printf("Method %s 's bytecode \n",newMethodBody.method->name->c_str()); + common->Printf("============================\n"); + swf_PrintStream(this,newMethodBody.code); + } + //memcpy(newMethodBody.code,bitstream.ReadData(newMethodBody.codeLength),newMethodBody.codeLength); + uint32 exception_count = bitstream.ReadEncodedU32( ); + for ( uint i = 0; i < exception_count; i++ ) { + auto &newExceptionInfo = newMethodBody.exceptions.Alloc( ); + ReadExceptionInfo( bitstream, newExceptionInfo ); + } + uint32 trait_count = bitstream.ReadEncodedU32( ); + for ( uint i = 0; i < trait_count; i++ ) { + auto &newTrait = newMethodBody.traits.Alloc( ); + ReadTraitsInfo( bitstream, newTrait ); + } +} + +void SWF_AbcFile::ReadExceptionInfo( idSWFBitStream &bitstream, swfException_info &newException ) +{ + newException.from = bitstream.ReadEncodedU32( ); + newException.to = bitstream.ReadEncodedU32(); + newException.target = bitstream.ReadEncodedU32(); + newException.exc_type = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; + newException.var_name = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; +} + +void SWF_AbcFile::ReadInstanceInfo( idSWFBitStream &bitstream, swfInstance_info &newInstancedata ) +{ + newInstancedata.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + newInstancedata.super_name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + + if (swf_abc_verbose.GetBool()) + { + traceMN( "newInstancedata.name", newInstancedata.name, constant_pool ); + traceMN( "newInstancedata.super_name", newInstancedata.super_name, constant_pool ); + } + + newInstancedata.flags = (swfInstanceFlags_t)bitstream.ReadU8(); + if ( (newInstancedata.flags & swfInstanceFlags_t::ClassProtectedNs) != 0 ) + newInstancedata.protectedNs = bitstream.ReadEncodedU32(); + uint32 interface_count = bitstream.ReadEncodedU32(); + + for (uint i =0; i < interface_count; i++ ) + newInstancedata.interfaces.Alloc() = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + + newInstancedata.iinit = &methods[bitstream.ReadEncodedU32()]; + + uint32 trait_count = bitstream.ReadEncodedU32( ); + + for (uint i = 0; i < trait_count; i++ ) { + auto & newTrait = newInstancedata.traits.Alloc(); + ReadTraitsInfo(bitstream,newTrait); + } + +} + +void SWF_AbcFile::ReadMethodInfo ( idSWFBitStream & bitstream , swfMethod_info & newMethod ) +{ + uint32 idx = 0; + newMethod.paramCount = bitstream.ReadEncodedU32(); + idx = bitstream.ReadEncodedU32(); + newMethod.returnType = &constant_pool.multinameInfos[idx]; + + for (uint i = 0; i < newMethod.paramCount; i++ ) { + idx = bitstream.ReadEncodedU32(); + newMethod.paramTypes.Alloc() = &constant_pool.multinameInfos[idx]; + } + idx = bitstream.ReadEncodedU32(); + newMethod.name = &constant_pool.utf8Strings[idx]; + newMethod.flags = bitstream.ReadU8(); + newMethod.options.option_count = 0; + if ( (newMethod.flags & swfMethod_info::HAS_OPTIONAL) != 0 ) + ReadOptionInfo(bitstream,newMethod.options); + + trace( "newMethod.name %s \n", newMethod.name->c_str() ); + + if ( (newMethod.flags & swfMethod_info::HAS_PARAM_NAMES) != 0 ) + { + trace( "newMethod.params %i \n", (int)newMethod.paramCount); + + for ( uint i = 0; i < newMethod.paramCount; i++ ) { + idx = bitstream.ReadEncodedU32( ); + newMethod.paramNames.Alloc() = &constant_pool.utf8Strings[idx]; + + trace( "newMethod.param %s \n", constant_pool.utf8Strings[idx].c_str() ); + } + } + +} + +//Remove Accessibility + +void idSWF::DoABC( idSWFBitStream & bitstream ) { + + SWF_AbcFile &newAbcFile = abcFile; + int strmSize = bitstream.Length( ) + 6; // codeLength(uin16) + recordLength(uin32) + uint32 flags = bitstream.ReadU32(); + idStr name = bitstream.ReadString(); + int dataSize = bitstream.Length( ) - name.Length( ); + common->Printf( "DoABC %s flags %i tagsize %i bytecode size %i \n", name.c_str( ), flags, strmSize, dataSize ); + + bitstream.ReadLittle( newAbcFile.minor_version ); + bitstream.ReadLittle( newAbcFile.major_version ); + + ReadConstantPoolInfo( bitstream, newAbcFile.constant_pool ); + SWF_AbcFile::traceConstantPool(newAbcFile.constant_pool); + + uint32 method_count = bitstream.ReadEncodedU32( ) ; + newAbcFile.methods.AssureSize(method_count); + trace("method_count %i \n", method_count ); + for ( uint i = 0; i < method_count; i++ ) { + auto &newMethod = newAbcFile.methods[i]; + newAbcFile.ReadMethodInfo( bitstream, newMethod ); + } + + uint32 meta_count = bitstream.ReadEncodedU32( ); + newAbcFile.metadatas.AssureSize(meta_count); + trace( "meta_count %i \n", meta_count ); + for ( uint i = 0; i < meta_count; i++ ) { + auto &newMeta = newAbcFile.metadatas[i]; + newAbcFile.ReadMetaDataInfo( bitstream, newMeta ); + } + + newAbcFile.class_count = bitstream.ReadEncodedU32(); + newAbcFile.instances.AssureSize(newAbcFile.class_count); + trace( "class_count %i (Instance) \n", newAbcFile.class_count ); + for ( uint i = 0; i < newAbcFile.class_count ; i++ ) { + auto &newInstance = newAbcFile.instances[i]; + newAbcFile.ReadInstanceInfo( bitstream, newInstance ); + } + + trace( "class_count %i (Class) \n", newAbcFile.class_count ); + newAbcFile.classes.AssureSize(newAbcFile.class_count); + for ( uint i = 0; i < newAbcFile.class_count ; i++ ) { + auto &newClass = newAbcFile.classes[i]; + newAbcFile.ReadClassInfo( bitstream, newClass ); + } + + uint32 script_count = bitstream.ReadEncodedU32( ); + newAbcFile.scripts.AssureSize( script_count ); + trace( "script_count %i \n", script_count ); + for ( uint i = 0; i < script_count; i++ ) { + auto &newScript = newAbcFile.scripts[i]; + newAbcFile.ReadScriptInfo( bitstream, newScript ); + } + + uint32 methBody_count = bitstream.ReadEncodedU32( ); + newAbcFile.method_bodies.AssureSize(methBody_count); + trace( "methBody_count %i \n", methBody_count ); + for ( uint i = 0; i < methBody_count; i++ ) { + + auto &newMethBody = newAbcFile.method_bodies[i]; + newAbcFile.ReadMethodBodyInfo( bitstream, newMethBody ); + } + + //Create trait objects + //resolve subclass/superclass relations. +} + +void idSWF::SymbolClass( idSWFBitStream &bitstream ) { + + //Header RECORDHEADER Tag type = 76 + //NumSymbols UI16 Number of symbols that will be associated by this tag. + //Tag1 U16 The 16 - bit character tag ID for the symbol to associate + //Name1 STRING The fully - qualified name of the ActionScript 3.0 class with which to associate this symbol.The class must have already been declared by a DoABC tag. + //... ... ... + //TagN U16 Tag ID for symbol N + //NameN STRING Fully - qualified class name for symbol N + uint16 numSymbols = bitstream.ReadU16(); + for (uint i = 0 ; i < numSymbols; i++ ) + { + auto & newSymbol = symbolClasses.symbols.Alloc(); + newSymbol.tag = bitstream.ReadU16( ); + newSymbol.name = bitstream.ReadString( ); + common->Printf("SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i,newSymbol.tag,newSymbol.name.c_str()); + } + + //load bytecode +} + + diff --git a/neo/swf/SWF_Abc.h b/neo/swf/SWF_Abc.h new file mode 100644 index 0000000000..344c109b55 --- /dev/null +++ b/neo/swf/SWF_Abc.h @@ -0,0 +1,229 @@ +#pragma once + +#include "SWF_Enums.h" + +struct swfMultiname +{ + swfConstantKind_t type; + uint32 nameIndex; + uint32 index; + uint32 nameIndexT; //second Multiname for types + uint32 indexT; // +}; + +struct swfConstant_pool_info +{ + idList integers; //u30 int_count s32 integer[int_count] + idList uIntegers; //u30 uint_count u32 uinteger[uint_count] + idList doubles; //u30 double_count d64 double[double_count] + idStrList utf8Strings; //u30 string_count string_info string[string_count] (char is 16bit code point) + idList namespaceKinds; //u30 namespace_count namespace_info namespace[namespace_count] (namespaceinfo_t.kind) + idStrPtrList namespaceNames; //u30 namespace_count namespace_info namespace[namespace_count] (namespaceinfo_t.name) + idList namespaceSets; //u30 ns_set_count ns_set_info ns_set[ns_set_count] + idList multinameInfos; //u30 multiname_count multiname_info multiname[multiname_count] +}; + +struct swfMetadata_info +{ + struct item { //item_info + idStrPtr key; //u30 key + idStrPtr value; //u30 value + }; + idStrPtr name; //u30 name + idList items; //u30 item_count item_info items[item_count] +}; + +struct swfOption_info +{ + struct item { //option_detail + uint32 val; //u30 val + swfConstantKind_t kind; //u8 kind + }; + uint32 option_count; //u30 option_count + idList options; //option_detail option[option_count] +}; + +struct swfMethod_body_info; +struct swfMethod_info +{ + //zero before use. + enum Flags { + NEED_ARGUMENTS = 0x01, // Suggests to the run - time that an �arguments� object( as specified by the ActionScript 3.0 Language Reference ) be created.Must not be used together with NEED_REST.See Chapter 3. + NEED_ACTIVATION = 0x02, // Must be set if this method uses the newactivation opcode. + NEED_REST = 0x04, // This flag creates an ActionScript 3.0 rest arguments array.Must not be used with NEED_ARGUMENTS.See Chapter 3. + HAS_OPTIONAL = 0x08, // Must be set if this method has optional parameters andthe options field is present in this method_info structure. + IGNORE_REST = 0x10, + NATIVE = 0x20, + SET_DXNS = 0x40, // Must be set if this method uses the dxns or dxnslate opcodes. + HAS_PARAM_NAMES = 0x80, // Must be set when the param_names field is present in this method_info structure. + }; + + uint32 paramCount; //u30 param_count + swfMultiname* returnType; //u30 return_type + idList paramTypes; //u30 param_count //u30 param_type[param_count] + idStrPtr name; //u30 name + uint8 flags; //u8 flags + swfOption_info options; //option_info options + idStrPtrList paramNames; // ( param_info ) param_names u30 param_name[param_count] + + swfMethod_body_info * body = nullptr; +}; + +struct swfTraits_info +{ + enum Attrib { // upper 4 bits of kind + Final = 0x1, // Is used with Trait_Method, Trait_Getter andTrait_Setter.It marks a method that cannot be overridden by a sub - class + Override = 0x2, // Is used with Trait_Method, Trait_Getter andTrait_Setter.It marks a method that has been overridden in this class + Metadata = 0x4, // Is used to signal that the fields metadata_count and metadata follow the data field in the traits_info entry + }; + enum Type { + Trait_Slot = 0, + Trait_Method = 1, + Trait_Getter = 2, + Trait_Setter = 3, + Trait_Class = 4, + Trait_Function = 5, + Trait_Const = 6, + Trait_Count = Trait_Const + 1, + Trait_Mask = 15 + }; + swfMultiname* name; //u30 name + uint8 kind; //u8 kind + void* data; //u8 data[] + idList metadatas; //u30 metadata_count u30 metadata[metadata_count] +}; + +struct swfInstance_info +{ + swfMultiname* name; //u30 name + swfMultiname* super_name; //u30 super_name + swfInstanceFlags_t flags; //u8 flags + uint32 protectedNs; //u30 protectedNs + idList interfaces; //u30 intrf_count u30 interface[intrf_count] + swfMethod_info* iinit; //u30 iinit + idList traits; //u30 trait_count traits_info trait[trait_count] +}; + +struct swfTrait_slot +{ + uint32 slot_id; //u30 slot_id + swfMultiname* type_name; //u30 type_name + uint32 vindex; //u30 vindex + uint8 vkind; //u8 vkind +}; + +struct swfClass_info +{ + swfMethod_info* cinit; //u30 cinit + idList traits; //u30 trait_count traits_info traits[trait_count] +}; + +struct swfTrait_class +{ + uint32 slot_id; //u30 slot_id + swfClass_info* classi; //u30 classi +}; + +struct swfTrait_function { + uint32 slot_id; //u30 slot_id + swfMethod_info * func; //u30 function +}; + +struct swfTrait_method { + uint32 disp_id; //u30 disp_id + swfMethod_info * method; //u30 method +}; + +struct swfScript_info +{ + swfMethod_info* init; //u30 init + idList traits; //u30 trait_count traits_info traits[trait_count] +}; + +struct swfException_info +{ + uint32 from; //u30 from + uint32 to; //u30 to + uint32 target; //u30 target + idStrPtr exc_type; //u30 exc_type + idStrPtr var_name; //u30 var_name +}; + +struct swfMethod_body_info +{ + swfMethod_info * method; //u30 method + uint32 max_stack; //u30 max_stack + uint32 localCount; //u30 local_count + uint32 initScopeDepth; //u30 init_scope_depth + uint32 maxScopeDepth; //u30 max_scope_depth + uint32 codeLength; //u30 code_length + idSWFBitStream code; //u8 code[code_length] + idList exceptions; //u30 exception_count exception_info exception[exception_count] + idList traits; //u30 trait_count traits_info traits[trait_count] +}; + +class idSWFScriptObject; +struct SWF_AbcFile +{ + template + T *GetTrait( const swfTraits_info &trait, idSWFScriptObject * globals = nullptr ); + + void ReadMethodInfo ( idSWFBitStream &bitstream, swfMethod_info &newMethod ); + void ReadOptionInfo ( idSWFBitStream &bitstream, swfOption_info &newOption ); + void ReadMetaDataInfo ( idSWFBitStream &bitstream, swfMetadata_info &newMetadata ); + void ReadInstanceInfo ( idSWFBitStream &bitstream, swfInstance_info &newInstancedata ); + void ReadTraitData ( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ); + void ReadTraitsInfo ( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ); + void ReadClassInfo ( idSWFBitStream &bitstream, swfClass_info &newClassData ); + void ReadScriptInfo ( idSWFBitStream &bitstream, swfScript_info &newScriptData ); + void ReadMethodBodyInfo ( idSWFBitStream &bitstream, swfMethod_body_info &newMethodBody ); + void ReadExceptionInfo ( idSWFBitStream &bitstream, swfException_info &newException ); + + static idStr asString( swfConstantKind_t kind, swfConstant_pool_info &constant_pool ); + static idStr asString( swfMultiname *mn, swfConstant_pool_info &constant_pool, bool prefix = true ); + static void traceMN( const char *name, swfMultiname *mn, swfConstant_pool_info &constant_pool ); + static void traceConstantPool( swfConstant_pool_info &constant_pool ); + + uint16 minor_version; + uint16 major_version; + swfConstant_pool_info constant_pool; + idList methods; //u30 method_count method_info method[method_count] + idList metadatas; //u30 metadata_count metadata_info metadata[metadata_count] + uint32 class_count; //u30 class_count + idList instances; //instance_info instance[class_count] + idList classes; //class_info class[class_count] + idList scripts; //u30 script_count script_info script[script_count] + idList method_bodies; //u30 method_body_count method_body_info method_body[method_body_count] +}; + +struct SWF_SymbolClass +{ + struct Item + { + uint16 tag; + idStr name; + }; + idList symbols; +}; + +enum SWFAbcOpcode { +#define ABC_OP(operandCount, canThrow, stack, internalOnly, nameToken) OP_##nameToken, +#define ABC_UNUSED_OP(operandCount, canThrow, stack, internalOnly, nameToken) ABC_OP(operandCount, canThrow, stack, internalOnly, nameToken) +#include "opcodes.tbl" +#undef ABC_OP +#undef ABC_UNUSED_OP + + //----- + OP_end_of_op_codes +}; + +struct AbcOpcodeInfo { + int8_t operandCount; // uses -1 for "invalid", we can avoid that if necessary + int8_t canThrow; // always 0 or 1 + int8_t stack; // stack movement not taking into account run-time names or function arguments + uint16_t wordCode; // a map used during translation + const char *name; // instruction name or OP_0xNN for undefined instructions #IFDEF DEBUGGER +}; + +extern const AbcOpcodeInfo opcodeInfo[]; +extern const unsigned char kindToPushOp[]; diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index 6951682b48..ea39e39efe 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -85,6 +85,20 @@ class idSWFBitStream uint32 ReadU32(); int16 ReadS16(); int32 ReadS32(); + + template< typename T > + T ReadEncoded(){ + T result = 0; + for ( int i = 0; i < 5; i++ ) { + byte b = ReadU8( ); + result |= ( b & 0x7F ) << ( 7 * i ); + if ( ( b & 0x80 ) == 0 ) { + return result; + } + } + return result; + } + uint32 ReadEncodedU32(); float ReadFixed8(); float ReadFixed16(); diff --git a/neo/swf/SWF_Dictionary.cpp b/neo/swf/SWF_Dictionary.cpp index 215219727f..5e334d3beb 100644 --- a/neo/swf/SWF_Dictionary.cpp +++ b/neo/swf/SWF_Dictionary.cpp @@ -43,7 +43,10 @@ idSWFDictionaryEntry::idSWFDictionaryEntry() : edittext( NULL ), imageSize( 0, 0 ), imageAtlasOffset( 0, 0 ), - channelScale( 1.0f, 1.0f, 1.0f, 1.0f ) + channelScale( 1.0f, 1.0f, 1.0f, 1.0f ), + scriptClass( ), + resolved ( false ), + name( NULL ) { } @@ -78,6 +81,9 @@ idSWFDictionaryEntry& idSWFDictionaryEntry::operator=( idSWFDictionaryEntry& oth edittext = other.edittext; imageSize = other.imageSize; imageAtlasOffset = other.imageAtlasOffset; + scriptClass = other.scriptClass; + resolved = other.resolved; + name = other.name; other.type = SWF_DICT_NULL; other.material = NULL; other.shape = NULL; @@ -85,6 +91,9 @@ idSWFDictionaryEntry& idSWFDictionaryEntry::operator=( idSWFDictionaryEntry& oth other.font = NULL; other.text = NULL; other.edittext = NULL; + other.resolved = false; + other.name = NULL; + other.scriptClass = idSWFScriptVar(); return *this; } diff --git a/neo/swf/SWF_Enums.h b/neo/swf/SWF_Enums.h index 3247bcfe35..f5e115b39d 100644 --- a/neo/swf/SWF_Enums.h +++ b/neo/swf/SWF_Enums.h @@ -28,7 +28,53 @@ If you have questions concerning this license or the applicable additional terms #ifndef __SWF_ENUMS_H__ #define __SWF_ENUMS_H__ -enum swfDictType_t + +enum swfInstanceFlags_t +{ + ClassSealed = 0x01, //The class is sealed: properties can not be dynamically added to instances of the class. + ClassFinal = 0x02, //The class is final : it cannot be a base class for any other class. + ClassInterface = 0x04, //The class is an interface. + ClassProtectedNs = 0x08, //The class uses its protected namespace andthe protectedNs +}; + +enum swfConstantKind_t +{ + unused_0x00 = 0x00, + Utf8 = 0x01, +#ifdef SWF_FLOAT + Float = 0x02, +#endif + Int = 0x03, + UInt = 0x04, + PrivateNs = 0x05, // non-shared namespace + Double = 0x06, + Qname = 0x07, // o.ns::name, ct ns, ct name + Namespace = 0x08, + Multiname = 0x09, // o.name, ct nsset, ct name + False = 0x0A, + True = 0x0B, + Null = 0x0C, + QnameA = 0x0D, // o.@ns::name, ct ns, ct attr-name + MultinameA = 0x0E, // o.@name, ct attr-name + RTQname = 0x0F, // o.ns::name, rt ns, ct name + RTQnameA = 0x10, // o.@ns::name, rt ns, ct attr-name + RTQnameL = 0x11, // o.ns::[name], rt ns, rt name + RTQnameLA = 0x12, // o.@ns::[name], rt ns, rt attr-name + NamespaceSet = 0x15, + PackageNamespace = 0x16, + PackageInternalNs = 0x17, + ProtectedNamespace = 0x18, + ExplicitNamespace = 0x19, + StaticProtectedNs = 0x1A, + MultinameL = 0x1B, + MultinameLA = 0x1C, + TypeName = 0x1D, +#ifdef SWF_FLOAT + Float4 = 0x1E, +#endif +}; + +enum swfDictType_t { SWF_DICT_NULL, SWF_DICT_IMAGE, diff --git a/neo/swf/SWF_EventDispatcher.cpp b/neo/swf/SWF_EventDispatcher.cpp new file mode 100644 index 0000000000..17aaa9567b --- /dev/null +++ b/neo/swf/SWF_EventDispatcher.cpp @@ -0,0 +1,158 @@ + +/* +=========================================================================== + +Copyright (C) 2022 HvanGinneken + +=========================================================================== +*/ +#include "precompiled.h" +#pragma hdrstop + +#include "SWF_EventDispatcher.h" + +/* +======================== +idSWFScriptObject_EventDispatcherPrototype +======================== +*/ +#define SWF_EVENTDISPATCHER_FUNCTION_DEFINE( x ) idSWFScriptVar idSWFScriptObject_EventDispatcherPrototype::idSWFScriptFunction_##x::Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) +#define SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( x ) idSWFScriptVar idSWFScriptObject_EventDispatcherPrototype::idSWFScriptNativeVar_##x::Get( class idSWFScriptObject * object ) +#define SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( x ) void idSWFScriptObject_EventDispatcherPrototype::idSWFScriptNativeVar_##x::Set( class idSWFScriptObject * object, const idSWFScriptVar & value ) + +#define SWF_EVENTDISPATCHER_PTHIS_FUNC( x ) idSWFScriptObject * pThis = thisObject ? thisObject : NULL; if ( !verify( pThis != NULL ) ) { idLib::Warning( "SWF: tried to call " x " on NULL object" ); return idSWFScriptVar(); } +#define SWF_EVENTDISPATCHER_PTHIS_GET( x ) idSWFScriptObject * pThis = object ? object : NULL; if ( pThis == NULL ) { return idSWFScriptVar(); } +#define SWF_EVENTDISPATCHER_PTHIS_SET( x ) idSWFScriptObject * pThis = object ? object : NULL; if ( pThis == NULL ) { return; } + +#define SWF_EVENTDISPATCHER_FUNCTION_SET( x ) scriptFunction_##x.AddRef(); Set( #x, &scriptFunction_##x ); +#define SWF_EVENTDISPATCHER_NATIVE_VAR_SET( x ) SetNative( #x, &swfScriptVar_##x ); + + +idSWFScriptObject_EventDispatcherPrototype::idSWFScriptObject_EventDispatcherPrototype() +{ + SWF_EVENTDISPATCHER_NATIVE_VAR_SET ( MouseEvent ); + SWF_EVENTDISPATCHER_NATIVE_VAR_SET ( Event ); + SWF_EVENTDISPATCHER_FUNCTION_SET( addEventListener ); +} + +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( MouseEvent ){} +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( Event ){} + +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( MouseEvent ) { + static idSWFScriptObject * mouseEventObj = nullptr; + if (mouseEventObj == nullptr) + { + mouseEventObj = idSWFScriptObject::Alloc( ); + idSWFScriptObject *eventParms = idSWFScriptObject::Alloc( ); + + eventParms->Set( "type", "MouseEvent" ); + mouseEventObj->Set( "[MouseEvent]", eventParms ); + //constants + mouseEventObj->Set( "CLICK", "click" ); + mouseEventObj->Set( "CONTEXT_MENU", "contextMenu" ); + mouseEventObj->Set( "DOUBLE_CLICK", "doubleClick" ); + mouseEventObj->Set( "MIDDLE_CLICK", "middleClick" ); + mouseEventObj->Set( "MIDDLE_MOUSE_DOWN", "middleMouseDown" ); + mouseEventObj->Set( "MIDDLE_MOUSE_UP", "middleMouseUp" ); + mouseEventObj->Set( "MOUSE_DOWN", "mouseDown" ); + mouseEventObj->Set( "MOUSE_MOVE", "mouseMove" ); + mouseEventObj->Set( "MOUSE_OUT", "mouseOut" ); + mouseEventObj->Set( "MOUSE_OVER", "mouseOver" ); + mouseEventObj->Set( "MOUSE_UP", "mouseUp" ); + mouseEventObj->Set( "MOUSE_WHEEL ", "mouseWheel" ); + mouseEventObj->Set( "RELEASE_OUTSIDE", "releaseOutside" ); + mouseEventObj->Set( "RIGHT_CLICK", "rightClick" ); + mouseEventObj->Set( "RIGHT_MOUSE_DOWN", "rightMouseDown" ); + mouseEventObj->Set( "RIGHT_MOUSE_UP", "rightMouseUp" ); + mouseEventObj->Set( "ROLL_OUT", "rollOut" ); + mouseEventObj->Set( "ROLL_OVER", "rollOver" ); + } + return mouseEventObj; +} + +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( Event ) { + static idSWFScriptObject *eventObj = nullptr; + if ( eventObj == nullptr ) { + eventObj = idSWFScriptObject::Alloc( ); + idSWFScriptObject *eventParms = idSWFScriptObject::Alloc( ); + + eventParms->Set( "type", "Event" ); + eventObj->Set( "[Event]", eventParms ); + + //constants + eventObj->Set( "ACTIVATE", "activate" ); + eventObj->Set( "ADDED", "added" ); + eventObj->Set( "ADDED_TO_STAGE", "addedToStage" ); + eventObj->Set( "BROWSER_ZOOM_CHANGE", "browserZoomChange" ); + eventObj->Set( "CANCEL", "cancel" ); + eventObj->Set( "CHANGE", "change" ); + eventObj->Set( "CHANNEL_MESSAGE", "channelMessage" ); + eventObj->Set( "CHANNEL_STATE", "channelState" ); + eventObj->Set( "CLEAR", "clear" ); + eventObj->Set( "CLOSE", "close" ); + eventObj->Set( "CLOSING", "closing" ); + eventObj->Set( "COMPLETE", "complete" ); + eventObj->Set( "CONNECT", "connect" ); + eventObj->Set( "CONTEXT3D_CREATE", "context3DCreate" ); + eventObj->Set( "COPY", "copy" ); + eventObj->Set( "CUT", "cut" ); + eventObj->Set( "DEACTIVATE", "deactivate" ); + eventObj->Set( "DISPLAYING", "displaying" ); + eventObj->Set( "ENTER_FRAME", "enterFrame" ); + eventObj->Set( "EXIT_FRAME", "exitFrame" ); + eventObj->Set( "EXITING", "exiting" ); + eventObj->Set( "FRAME_CONSTRUCTED", "frameConstructed" ); + eventObj->Set( "FRAME_LABEL", "frameLabel" ); + eventObj->Set( "FULLSCREEN", "fullScreen" ); + eventObj->Set( "HTML_BOUNDS_CHANGE", "htmlBoundsChange" ); + eventObj->Set( "HTML_DOM_INITIALIZE", "htmlDOMInitialize" ); + eventObj->Set( "HTML_RENDER", "htmlRender" ); + eventObj->Set( "ID3", "id3" ); + eventObj->Set( "INIT", "init" ); + eventObj->Set( "LOCATION_CHANGE", "locationChange" ); + eventObj->Set( "MOUSE_LEAVE", "mouseLeave" ); + eventObj->Set( "NETWORK_CHANGE", "networkChange" ); + eventObj->Set( "OPEN", "open" ); + eventObj->Set( "PASTE", "paste" ); + eventObj->Set( "PREPARING", "preparing" ); + eventObj->Set( "REMOVED", "removed" ); + eventObj->Set( "REMOVED_FROM_STAGE", "removedFromStage" ); + eventObj->Set( "RENDER", "render" ); + eventObj->Set( "RESIZE", "resize" ); + eventObj->Set( "SCROLL", "scroll" ); + eventObj->Set( "SELECT", "select" ); + eventObj->Set( "SELECT_ALL", "selectAll" ); + eventObj->Set( "SOUND_COMPLETE", "soundComplete" ); + eventObj->Set( "STANDARD_ERROR_CLOSE", "standardErrorClose" ); + eventObj->Set( "STANDARD_INPUT_CLOSE", "standardInputClose" ); + eventObj->Set( "STANDARD_OUTPUT_CLOSE", "standardOutputClose" ); + eventObj->Set( "SUSPEND", "suspend" ); + eventObj->Set( "TAB_CHILDREN_CHANGE", "tabChildrenChange" ); + eventObj->Set( "TAB_ENABLED_CHANGE", "tabEnabledChange" ); + eventObj->Set( "TAB_INDEX_CHANGE", "tabIndexChange" ); + eventObj->Set( "TEXT_INTERACTION_MODE_CHANGE", "textInteractionModeChange" ); + eventObj->Set( "TEXTURE_READY", "textureReady" ); + eventObj->Set( "UNLOAD", "unload" ); + eventObj->Set( "USER_IDLE", "userIdle" ); + eventObj->Set( "USER_PRESENT", "userPresent" ); + eventObj->Set( "VIDEO_FRAME", "videoFrame" ); + eventObj->Set( "WORKER_STATE", "workerState" ); + } + return eventObj; +} + +SWF_EVENTDISPATCHER_FUNCTION_DEFINE( addEventListener ) +{ + SWF_EVENTDISPATCHER_PTHIS_FUNC( "addEventListener" ); + swfNamedVar_t * dispatcher = thisObject->GetVariable("__eventDispatcher__",true); + + if (dispatcher->value.IsUndefined() ) + dispatcher->value.SetObject(idSWFScriptObject::Alloc()); + + dispatcher->value.GetObject()->Set(parms[1].ToString(),parms[0]); + common->DPrintf("{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(),parms[1].ToString().c_str(),parms[0].ToString().c_str()); + //add listener + return idSWFScriptVar( ); +} + + diff --git a/neo/swf/SWF_EventDispatcher.h b/neo/swf/SWF_EventDispatcher.h new file mode 100644 index 0000000000..8cbae79613 --- /dev/null +++ b/neo/swf/SWF_EventDispatcher.h @@ -0,0 +1,63 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +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. + +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. + +=========================================================================== +*/ +#ifndef __SWF_EVENTDISPATCHER_H__ +#define __SWF_EVENTDISPATCHER_H__ + +#include "SWF_ScriptObject.h" +#include "SWF_ParmList.h" +#include "SWF_Types.h" +#include "SWF_Sprites.h" +#include "swf.h" +#include "SWF_Abc.h" + +class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject { +public: + idSWFScriptObject_EventDispatcherPrototype( ); +#define SWF_EVENTDISPATCHER_FUNCTION_DECLARE( x ) \ + class idSWFScriptFunction_##x : public idSWFScriptFunction { \ + public: \ + void AddRef() {} \ + void Release() {} \ + idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ + } scriptFunction_##x + + SWF_NATIVE_VAR_DECLARE( MouseEvent ); + SWF_NATIVE_VAR_DECLARE( Event ); + + SWF_EVENTDISPATCHER_FUNCTION_DECLARE( addEventListener ); + //SWF_EVENTDISPATHCER_FUNCTION_DECLARE( removeEventListener ); + //SWF_EVENTDISPATHCER_FUNCTION_DECLARE( dispatchEvent ); + //SWF_EVENTDISPATHCER_FUNCTION_DECLARE( dispatchQueue ); + + //object.addEventListener = _fEventDispatcher.addEventListener; + //object.removeEventListener = _fEventDispatcher.removeEventListener; + //object.dispatchEvent = _fEventDispatcher.dispatchEvent; + //object.dispatchQueue = _fEventDispatcher.dispatchQueue; +}; + +#endif //__SWF_EVENTDISPATCHER_H__ \ No newline at end of file diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 57ddfdb1f3..65b1980ce7 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -28,6 +28,32 @@ If you have questions concerning this license or the applicable additional terms */ #include "precompiled.h" #pragma hdrstop +idSWFScriptObject* GetMouseEventDispatcher( idSWFScriptObject *object ) { + idSWFScriptObject *dispatcher = nullptr; + if ( object->HasValidProperty( "__eventDispatcher__" ) ) { + dispatcher = object->Get( "__eventDispatcher__" ).GetObject( ); + if ( dispatcher->HasValidProperty( "click" ) + || dispatcher->HasValidProperty( "contextMenu" ) + || dispatcher->HasValidProperty( "doubleClick" ) + || dispatcher->HasValidProperty( "middleClick" ) + || dispatcher->HasValidProperty( "middleMouseDown" ) + || dispatcher->HasValidProperty( "middleMouseUp" ) + || dispatcher->HasValidProperty( "mouseDown" ) + || dispatcher->HasValidProperty( "mouseMove" ) + || dispatcher->HasValidProperty( "mouseOut" ) + || dispatcher->HasValidProperty( "mouseOver" ) + || dispatcher->HasValidProperty( "mouseUp" ) + || dispatcher->HasValidProperty( "mouseWheel" ) + || dispatcher->HasValidProperty( "releaseOutside" ) + || dispatcher->HasValidProperty( "rightClick" ) + || dispatcher->HasValidProperty( "rightMouseDown" ) + || dispatcher->HasValidProperty( "rightMouseUp" ) + || dispatcher->HasValidProperty( "rollOut" ) + || dispatcher->HasValidProperty( "rollOver" ) ) + return dispatcher; + } + return nullptr; +} /* =================== @@ -50,15 +76,23 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw { return NULL; } + + idSWFScriptObject * dispatcher = GetMouseEventDispatcher( spriteInstance->scriptObject ); - if( spriteInstance->scriptObject->HasValidProperty( "onRelease" ) + if (dispatcher!=nullptr) { + parentObject = spriteInstance->scriptObject; + }else + { + if ( spriteInstance->scriptObject->HasValidProperty( "onRelease" ) || spriteInstance->scriptObject->HasValidProperty( "onPress" ) || spriteInstance->scriptObject->HasValidProperty( "onRollOver" ) || spriteInstance->scriptObject->HasValidProperty( "onRollOut" ) || spriteInstance->scriptObject->HasValidProperty( "onDrag" ) - ) - { - parentObject = spriteInstance->scriptObject; + || spriteInstance->scriptObject->HasValidProperty( "onDrag" ) + ) + { + parentObject = spriteInstance->scriptObject; + } } // rather than returning the first object we find, we actually want to return the last object we find @@ -122,21 +156,29 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw else if( entry->type == SWF_DICT_MORPH ) { // FIXME: this should be roughly the same as SWF_DICT_SHAPE - } - else if( entry->type == SWF_DICT_TEXT ) - { + + //} else if( entry->type == SWF_DICT_TEXT ) + //{ // FIXME: this should be roughly the same as SWF_DICT_SHAPE } - else if( entry->type == SWF_DICT_EDITTEXT ) + else if( entry->type == SWF_DICT_EDITTEXT || entry->type == SWF_DICT_TEXT) { idSWFScriptObject* editObject = NULL; - if( display.textInstance->scriptObject.HasProperty( "onRelease" ) || display.textInstance->scriptObject.HasProperty( "onPress" ) ) + idSWFScriptObject * textdispatcher = nullptr; + if ( display.textInstance ) + { + dispatcher = GetMouseEventDispatcher( &display.textInstance->scriptObject ); + } + if ( dispatcher!=nullptr ) + { + editObject = &display.textInstance->scriptObject; + }else if ( display.textInstance && ( display.textInstance->scriptObject.HasProperty( "onRelease" ) || display.textInstance->scriptObject.HasProperty( "onPress" ) ) ) { // if the edit box itself can be clicked, then we want to return it when it's clicked on editObject = &display.textInstance->scriptObject; } - else if( parentObject != NULL ) + else if ( !dispatcher && parentObject != NULL ) { // otherwise, we want to return the parent object editObject = parentObject; @@ -147,7 +189,7 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw continue; } - if( display.textInstance->text.IsEmpty() ) + if(!display.textInstance || display.textInstance->text.IsEmpty() ) { continue; } @@ -254,7 +296,8 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) { mouseEnabled = true; idSWFScriptVar var; - if( event->evValue2 ) + idSWFScriptVar eventDispatcher = mainspriteInstance->GetScriptObject()->Get( "__eventDispatcher__" ); + if ( event->evValue2 ) { idSWFScriptVar waitInput = globals->Get( "waitInput" ); @@ -277,8 +320,35 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) mouseObject = hitObject; mouseObject->AddRef(); + eventDispatcher = hitObject->Get( "__eventDispatcher__" ); + + if (!eventDispatcher.IsUndefined() && !var.IsFunction()) + { + var = eventDispatcher.GetObject( )->Get( "click" ); + if ( !var.IsFunction( ) ) + var = eventDispatcher.GetObject( )->Get( "mouseDown" ); + } + if ( var.IsFunction( ) ) + { + idSWFScriptVar eventArg; + auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); + eventArg.SetObject( idSWFScriptObject::Alloc( ) ); + eventArg.GetObject( )->DeepCopy( eventObj ); + idSWFParmList parms; + parms.Append( eventArg ); + if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + { + ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + } + var.GetFunction( )->Call( hitObject, parms ); + parms.Clear( ); + return false; + } + var = hitObject->Get( "onPress" ); - if( var.IsFunction() ) + if ( var.IsFunction( ) ) { idSWFParmList parms; parms.Append( event->inputDevice ); @@ -304,11 +374,37 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) parms.Append( hitObject ); Invoke( "setHitObject", parms ); - } - else + } else { - if( mouseObject ) + if ( mouseObject ) { + eventDispatcher = mouseObject->Get( "__eventDispatcher__" ); + + if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + { + var = eventDispatcher.GetObject( )->Get( "mouseUp" ); + } + if ( var.IsFunction( ) ) + { + idSWFScriptVar eventArg; + auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); + eventArg.SetObject( idSWFScriptObject::Alloc( ) ); + eventArg.GetObject( )->DeepCopy( eventObj ); + idSWFParmList parms; + parms.Append( eventArg ); + if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + { + ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + } + var.GetFunction( )->Call( mouseObject, parms ); + parms.Clear( ); + mouseObject->Release( ); + mouseObject = NULL; + return true; + } + var = mouseObject->Get( "onRelease" ); if( var.IsFunction() ) { @@ -494,15 +590,35 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) hasHitObject = false; } - if( hitObject != hoverObject ) - { + idSWFScriptVar eventDispatcher; + if ( hitObject != hoverObject ) { + // First check to see if we should call onRollOut on our previous hoverObject if( hoverObject != NULL ) { idSWFScriptVar var = hoverObject->Get( "onRollOut" ); - if( var.IsFunction() ) + + eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); + if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) { - var.GetFunction()->Call( hoverObject, idSWFParmList() ); + var = eventDispatcher.GetObject( )->Get( "mouseOut" ); + if ( var.IsFunction( ) ) { + idSWFScriptVar eventArg; + auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); + eventArg.SetObject( idSWFScriptObject::Alloc( ) ); + eventArg.GetObject( )->DeepCopy( eventObj ); + idSWFParmList parms; + parms.Append( eventArg ); + if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + var.GetFunction( )->Call( hoverObject, parms ); + parms.Clear( ); + retVal = true; + } + }else if ( var.IsFunction( ) ) { + var.GetFunction( )->Call( hoverObject, idSWFParmList( ) ); retVal = true; } hoverObject->Release(); @@ -514,9 +630,29 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) hoverObject = hitObject; hoverObject->AddRef(); idSWFScriptVar var = hitObject->Get( "onRollOver" ); - if( var.IsFunction() ) + + eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); + if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) { - var.GetFunction()->Call( hitObject, idSWFParmList() ); + var = eventDispatcher.GetObject( )->Get( "mouseOver" ); + if (var.IsFunction() ) + { + idSWFScriptVar eventArg; + auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); + eventArg.SetObject( idSWFScriptObject::Alloc( ) ); + eventArg.GetObject( )->DeepCopy( eventObj ); + idSWFParmList parms; + parms.Append( eventArg ); + if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + var.GetFunction( )->Call( hoverObject, parms ); + parms.Clear( ); + retVal = true; + } + } else if ( var.IsFunction( ) ) { + var.GetFunction( )->Call( hitObject, idSWFParmList( ) ); retVal = true; } } diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp new file mode 100644 index 0000000000..f25d2f5c55 --- /dev/null +++ b/neo/swf/SWF_Interpreter.cpp @@ -0,0 +1,789 @@ +#include "precompiled.h" +#pragma hdrstop + +//#include "SWF_Bitstream.h" +//#include "SWF_Enums.h" +//#include "SWF_Abc.h" +//#include "SWF_ScriptObject.h" +//#include "SWF_ScriptFunction.h" +//#include "framework/Common.h" + +inline int32 readS24( const byte *pc ) { + return ((uint16_t*)pc)[0] | ((int8_t*)pc)[2]<<16; +} + +inline uint32 readU30( const uint8_t *&pc ) { + uint32 result = 0; + for ( int i = 0; i < 5; i++ ) { + byte b = *pc++; + result |= ( b & 0x7F ) << ( 7 * i ); + if ( ( b & 0x80 ) == 0 ) { + return result; + } + } + return result; +} + +const AbcOpcodeInfo opcodeInfo[] = { + // For stack movement ("stk") only constant movement is accounted for; variable movement, + // as for arguments to CALL, CONSTRUCT, APPLYTYPE, et al, and for run-time parts of + // names, must be handled separately. + +#define ABC_OP(operandCount, canThrow, stack, internalOnly, nameToken) { operandCount, canThrow, stack , OP_##nameToken , #nameToken }, +#define ABC_UNUSED_OP(operandCount, canThrow, stack, internalOnly, nameToken) { operandCount, canThrow, stack , 0 , #nameToken }, + +#include "opcodes.tbl" + +#undef ABC_OP +#undef ABC_UNUSED_OP +#undef ABC_OP_F +}; + +void debugfile(SWF_AbcFile * file, idSWFBitStream &bitstream ) +{ + common->Printf(" debugfile %s\n",file->constant_pool.utf8Strings[bitstream.ReadEncodedU32()].c_str()); +} + +void debugline(SWF_AbcFile * file, idSWFBitStream &bitstream ) +{ + common->Printf(" debugline %i\n",(int)bitstream.ReadEncodedU32()); +} + +void swf_PrintStream(SWF_AbcFile * file, idSWFBitStream &bitstream ) { + //(case.*OP_)([A-Za-z0-9]*_?[A-Za-z0-9]*)(.*\n)(.*) + idSWFStack stack; + static idList codeMap; + idStr type; + const AbcOpcodeInfo * info = nullptr; + while ( bitstream.Tell() < bitstream.Length() ) { +#define DoWordCode( n ) case OP_##n: type = #n; info = &opcodeInfo[opCode]; break; +#define ExecWordCode( n ) case OP_##n: type = #n; info = &opcodeInfo[opCode]; n(file,bitstream); continue; + SWFAbcOpcode opCode = (SWFAbcOpcode) bitstream.ReadU8(); + switch ( opCode ) { + DoWordCode ( bkpt ); + DoWordCode ( nop ); + DoWordCode ( throw ); + DoWordCode ( getsuper ); + DoWordCode ( setsuper ); + DoWordCode ( dxns ); + DoWordCode ( dxnslate ); + DoWordCode ( kill ); + DoWordCode ( label ); + DoWordCode ( ifnlt ); + DoWordCode ( ifnle ); + DoWordCode ( ifngt ); + DoWordCode ( ifnge ); + DoWordCode ( jump ); + DoWordCode ( iftrue ); + DoWordCode ( iffalse ); + DoWordCode ( ifeq ); + DoWordCode ( ifne ); + DoWordCode ( iflt ); + DoWordCode ( ifle ); + DoWordCode ( ifgt ); + DoWordCode ( ifge ); + DoWordCode ( ifstricteq ); + DoWordCode ( ifstrictne ); + DoWordCode ( lookupswitch ); + DoWordCode ( pushwith ); + DoWordCode ( popscope ); + DoWordCode ( nextname ); + DoWordCode ( hasnext ); + DoWordCode ( pushnull ); + DoWordCode ( pushundefined ); + DoWordCode ( DISABLED_pushfloat ); + DoWordCode ( nextvalue ); + DoWordCode ( pushbyte ); + DoWordCode ( pushshort ); + DoWordCode ( pushtrue ); + DoWordCode ( pushfalse ); + DoWordCode ( pushnan ); + DoWordCode ( pop ); + DoWordCode ( dup ); + DoWordCode ( swap ); + DoWordCode ( pushstring ); + DoWordCode ( pushint ); + DoWordCode ( pushuint ); + DoWordCode ( pushdouble ); + DoWordCode ( pushscope ); + DoWordCode ( pushnamespace ); + DoWordCode ( hasnext2 ); + DoWordCode ( lix8 ); + DoWordCode ( lix16 ); + DoWordCode ( li8 ); + DoWordCode ( li16 ); + DoWordCode ( li32 ); + DoWordCode ( lf32 ); + DoWordCode ( lf64 ); + DoWordCode ( si8 ); + DoWordCode ( si16 ); + DoWordCode ( si32 ); + DoWordCode ( sf32 ); + DoWordCode ( sf64 ); + DoWordCode ( newfunction ); + DoWordCode ( call ); + DoWordCode ( construct ); + DoWordCode ( callmethod ); + DoWordCode ( callstatic ); + DoWordCode ( callsuper ); + DoWordCode ( callproperty ); + DoWordCode ( returnvoid ); + DoWordCode ( returnvalue ); + DoWordCode ( constructsuper ); + DoWordCode ( constructprop ); + DoWordCode ( callsuperid ); + DoWordCode ( callproplex ); + DoWordCode ( callinterface ); + DoWordCode ( callsupervoid ); + DoWordCode ( callpropvoid ); + DoWordCode ( sxi1 ); + DoWordCode ( sxi8 ); + DoWordCode ( sxi16 ); + DoWordCode ( applytype ); + DoWordCode ( DISABLED_pushfloat4 ); + DoWordCode ( newobject ); + DoWordCode ( newarray ); + DoWordCode ( newactivation ); + DoWordCode ( newclass ); + DoWordCode ( getdescendants ); + DoWordCode ( newcatch ); + DoWordCode ( findpropglobalstrict ); + DoWordCode ( findpropglobal ); + DoWordCode ( findpropstrict ); + DoWordCode ( findproperty ); + DoWordCode ( finddef ); + DoWordCode ( getlex ); + DoWordCode ( setproperty ); + DoWordCode ( getlocal ); + DoWordCode ( setlocal ); + DoWordCode ( getglobalscope ); + DoWordCode ( getscopeobject ); + DoWordCode ( getproperty ); + DoWordCode ( getouterscope ); + DoWordCode ( initproperty ); + DoWordCode( deleteproperty ); + DoWordCode ( getslot ); + DoWordCode ( setslot ); + DoWordCode ( getglobalslot ); + DoWordCode ( setglobalslot ); + DoWordCode ( convert_s ); + DoWordCode ( esc_xelem ); + DoWordCode ( esc_xattr ); + DoWordCode ( convert_i ); + DoWordCode ( convert_u ); + DoWordCode ( convert_d ); + DoWordCode ( convert_b ); + DoWordCode ( convert_o ); + DoWordCode ( checkfilter ); + //DoWordCode ( DISABLED_convert ); + //DoWordCode ( DISABLED_unplus ); + //DoWordCode ( DISABLED_convert ); + DoWordCode ( coerce ); + DoWordCode ( coerce_b ); + DoWordCode ( coerce_a ); + DoWordCode ( coerce_i ); + DoWordCode ( coerce_d ); + DoWordCode ( coerce_s ); + DoWordCode ( astype ); + DoWordCode ( astypelate ); + DoWordCode ( coerce_u ); + DoWordCode ( coerce_o ); + DoWordCode ( negate ); + DoWordCode ( increment ); + DoWordCode ( inclocal ); + DoWordCode ( decrement ); + DoWordCode ( declocal ); + DoWordCode ( typeof ); + DoWordCode ( not ); + DoWordCode ( bitnot ); + DoWordCode ( add ); + DoWordCode ( subtract ); + DoWordCode ( multiply ); + DoWordCode ( divide ); + DoWordCode ( modulo ); + DoWordCode ( lshift ); + DoWordCode ( rshift ); + DoWordCode ( urshift ); + DoWordCode ( bitand ); + DoWordCode ( bitor ); + DoWordCode ( bitxor ); + DoWordCode ( equals ); + DoWordCode ( strictequals ); + DoWordCode ( lessthan ); + DoWordCode ( lessequals ); + DoWordCode ( greaterthan ); + DoWordCode ( greaterequals ); + DoWordCode ( instanceof ); + DoWordCode ( istype ); + DoWordCode ( istypelate ); + DoWordCode ( in ); + DoWordCode ( increment_i ); + DoWordCode ( decrement_i ); + DoWordCode ( inclocal_i ); + DoWordCode ( declocal_i ); + DoWordCode ( negate_i ); + DoWordCode ( add_i ); + DoWordCode ( subtract_i ); + DoWordCode ( multiply_i ); + DoWordCode ( getlocal0 ); + DoWordCode ( getlocal1 ); + DoWordCode ( getlocal2 ); + DoWordCode ( getlocal3 ); + DoWordCode ( setlocal0 ); + DoWordCode ( setlocal1 ); + DoWordCode ( setlocal2 ); + DoWordCode ( setlocal3 ); + DoWordCode ( debug ); + ExecWordCode ( debugline ); + ExecWordCode ( debugfile ); + DoWordCode ( bkptline ); + DoWordCode ( timestamp ); + DoWordCode ( restargc ); + DoWordCode ( restarg ); + default: + common->Printf( "default %s %s\n", type.c_str( ) ,info ? info->name:"Empty"); + } + static const char * tabs[] = { " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "}; + if ( info && info->operandCount > 0 ) + bitstream.ReadData(info->operandCount); + common->Printf( " %s %s o %s%i \t s %s%i \n" , + info ? info->name:type.c_str( ), + tabs[int(18 - (int(idStr::Length(info->name))))], + info->operandCount > 0 ? "^2" : "^1" , + info->operandCount, + info->stack < 0 ? "^2" : "^1", + info->stack + ); + } + bitstream.Rewind(); +#undef DoWordCode +#undef ExecWordCode +} + +void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) +{ + const auto &cp = file->constant_pool; + const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + //search up scope stack. + for ( int i = scope.Num( ) - 1; i >= 0; i-- ) { + auto *s = scope[i]; + while ( s ) + if ( s->HasProperty( propName->c_str( ) ) ) { + stack.Alloc( ) = s->Get( propName->c_str( ) ); + return; + } else if ( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype( ) ) + s = s->GetPrototype( )->GetPrototype( ); + else + s = NULL; + } + common->Warning("idSWFScriptFunction_Script::findpropstrict cant find %s",propName->c_str()); + //search method closure, which is the stack up until a method call? +} + +void idSWFScriptFunction_Script::getlex( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) +{ + const auto &cp = file->constant_pool; + const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + //search up scope stack. + for ( int i = scope.Num( ) - 1; i >= 0; i-- ) { + auto *s = scope[i]; + while ( s ) + if ( s->HasProperty( propName->c_str( ) )) + { + stack.Alloc( ) = s->Get( propName->c_str( ) ); + return; + }else if (s->GetPrototype( ) && s->GetPrototype( )->GetPrototype() ) + s = s->GetPrototype( )->GetPrototype(); + else + s = NULL; + } +} + +void idSWFScriptFunction_Script::getscopeobject( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { + uint8 index = bitstream.ReadEncodedU32(); + stack.Alloc() = scope[scope.Num() - index]; +} + +void idSWFScriptFunction_Script::pushscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { + if (stack.Num() > 0) + { + if ( stack.A().IsObject() ) + scope.Alloc() = stack.A().GetObject(); + else + common->DWarning( "tried to push a non object onto scope"); + stack.Pop(1); + } +} + +void idSWFScriptFunction_Script::popscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { + scope.SetNum( scope.Num() - 1 ); +} + +void idSWFScriptFunction_Script::getlocal0(SWF_AbcFile* file, idSWFStack &stack, idSWFBitStream &bitstream ) { + stack.Alloc() = registers[0]; +} + +//The class's static initializer will be run when the newclass instruction +// is executed on the class_info entry for the class. +void idSWFScriptFunction_Script::newclass( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { + const auto &ci = file->classes[bitstream.ReadEncodedU32( )]; + idSWFScriptVar base = stack.A(); stack.Pop(1); + idSWFScriptVar* thisObj = ®isters[0]; + //find static intializer. + int a = 1; +} + +void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { + const auto &cp = file->constant_pool; + const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + uint32 arg_count = bitstream.ReadEncodedU32(); + + idSWFParmList parms(arg_count); + + for ( int i = 0; i < parms.Num( ); i++ ) { + parms[i] = stack.A( ); + stack.Pop( 1 ); + } + idSWFScriptVar & item = stack.A(); + if (item.IsFunction()) + item.GetFunction()->Call(registers[0].GetObject(),parms); + else if( item.IsObject() ) + { + auto func = item.GetObject()->Get( funcName->c_str() ); + if ( func.IsFunction( ) ) + { + if (!((idSWFScriptFunction_Script*)func.GetFunction())->GetScope()->Num()) + ((idSWFScriptFunction_Script*)func.GetFunction())->SetScope(*GetScope()); + func.GetFunction( )->Call( item.GetObject(), parms ); + } + } + stack.Pop(1); +} + +/* +======================== +idSWFScriptFunction_Script::RunAbc bytecode +======================== +*/ +idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject *thisObject, idSWFStack &stack, idSWFBitStream &bitstream ) { + static int abcCallstackLevel = -1; + idSWFSpriteInstance *thisSprite = thisObject->GetSprite( ); + idSWFSpriteInstance *currentTarget = thisSprite; + assert( abcFile ); + + abcCallstackLevel++; + if ( currentTarget == NULL ) { + thisSprite = currentTarget = defaultSprite; + } + + while ( bitstream.Tell( ) < bitstream.Length( ) ) { +#define ExecWordCode( n ) case OP_##n: n(abcFile,stack,bitstream); continue; +#define InlineWordCode( n ) case OP_##n: + SWFAbcOpcode opCode = (SWFAbcOpcode) bitstream.ReadU8(); + + switch ( opCode ) { + //ExecWordCode ( bkpt ); + //ExecWordCode ( nop ); + //ExecWordCode ( throw ); + //ExecWordCode ( getsuper ); + //ExecWordCode ( setsuper ); + //ExecWordCode ( dxns ); + //ExecWordCode ( dxnslate ); + //ExecWordCode ( kill ); + //ExecWordCode ( label ); + //ExecWordCode ( ifnlt ); + //ExecWordCode ( ifnle ); + //ExecWordCode ( ifngt ); + //ExecWordCode ( ifnge ); + //ExecWordCode ( jump ); + //ExecWordCode ( iftrue ); + //ExecWordCode ( iffalse ); + //ExecWordCode ( ifeq ); + //ExecWordCode ( ifne ); + //ExecWordCode ( iflt ); + //ExecWordCode ( ifle ); + //ExecWordCode ( ifgt ); + //ExecWordCode ( ifge ); + //ExecWordCode ( ifstricteq ); + //ExecWordCode ( ifstrictne ); + //ExecWordCode ( lookupswitch ); + //ExecWordCode ( pushwith ); + ExecWordCode ( popscope ); + //ExecWordCode ( nextname ); + //ExecWordCode ( hasnext ); + InlineWordCode( pushnull ) + stack.Append( idSWFScriptVar( NULL ) ); + continue; + //ExecWordCode ( pushundefined ); + InlineWordCode( pushundefined ) + stack.Append( idSWFScriptVar( ) ); + continue; + //ExecWordCode ( nextvalue ); + InlineWordCode ( pushbyte ) + stack.Append( idSWFScriptVar((int)bitstream.ReadU8())); + continue; + InlineWordCode ( pushshort ) + stack.Append( idSWFScriptVar((int)bitstream.ReadEncodedU32( ))); + continue; + InlineWordCode ( pushtrue ) + stack.Append( idSWFScriptVar( true ) ); + continue; + InlineWordCode ( pushfalse ) + stack.Append( idSWFScriptVar( false ) ); + continue; + //ExecWordCode ( pushnan ); + InlineWordCode ( pop ) + stack.Pop(1); + continue; + InlineWordCode ( dup ) + stack.Alloc() = idSWFScriptVar(stack.A()); + continue; + InlineWordCode( swap ) + common->FatalError("swap not implemented"); + continue; + InlineWordCode ( pushstring ) + { + const auto &cp = abcFile->constant_pool.utf8Strings; + const auto &mn = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptString(mn.c_str())); + continue; + } + InlineWordCode( pushint ) + { + const auto &cp = abcFile->constant_pool.integers; + const auto &val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( val ) ); + continue; + } + InlineWordCode ( pushuint ) + { + const auto &cp = abcFile->constant_pool.uIntegers; + const auto &val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( (int)val ) ); + continue; + } + InlineWordCode ( pushdouble ) + { + const auto &cp = abcFile->constant_pool.doubles; + const auto &val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( (float)val ) ); + continue; + } + ExecWordCode ( pushscope ); + //ExecWordCode ( pushnamespace ); + //ExecWordCode ( hasnext2 ); + //ExecWordCode ( lix8 ); + //ExecWordCode ( lix16 ); + //ExecWordCode ( li8 ); + //ExecWordCode ( li16 ); + //ExecWordCode ( li32 ); + //ExecWordCode ( lf32 ); + //ExecWordCode ( lf64 ); + //ExecWordCode ( si8 ); + //ExecWordCode ( si8 ); + //ExecWordCode ( si16 ); + //ExecWordCode ( si32 ); + //ExecWordCode ( sf32 ); + //ExecWordCode ( sf64 ); + //ExecWordCode ( newfunction ); + //ExecWordCode ( call ); + //ExecWordCode ( construct ); + //ExecWordCode ( callmethod ); + //ExecWordCode ( callstatic ); + InlineWordCode ( callsuper ) + { + common->FatalError("callsuper not implemented"); + continue; + } + InlineWordCode ( callproperty ) + {//fold this with callpropvoid. + const auto &cp = abcFile->constant_pool; + const auto &mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + uint32 arg_count = bitstream.ReadEncodedU32( ); + + idSWFParmList parms( arg_count ); + + for ( int i = 0; i < parms.Num( ); i++ ) { + parms[i] = stack.A( ); + stack.Pop( 1 ); + } + idSWFScriptVar &item = stack.A( ); + if ( item.IsFunction( ) ) + stack.Alloc() = item.GetFunction( )->Call( registers[0].GetObject( ), parms ); + else if ( item.IsObject( ) ) { + auto func = item.GetObject( )->Get( funcName->c_str( ) ); + if ( func.IsFunction( ) ) { + ( ( idSWFScriptFunction_Script * ) func.GetFunction( ) )->SetScope( *GetScope( ) ); + stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); + } + } + continue; + } + InlineWordCode ( returnvoid ) + { + if (scope[scope.Num()-1]) + scope[scope.Num()-1]->Release(); + + scope.SetNum(scope.Num()-1); + continue; + } + //ExecWordCode ( returnvalue ); + InlineWordCode ( constructsuper ) + { + uint32 args = bitstream.ReadEncodedU32( ); + stack.Pop( args ); + continue; + } + InlineWordCode ( constructprop ) + { + + //no need to call constructors. + const auto &cp = abcFile->constant_pool; + const auto &mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + uint32 arg_count = bitstream.ReadEncodedU32( ); + stack.Pop( arg_count ); + continue; + + + idSWFParmList parms( arg_count ); + + for ( int i = 0; i < parms.Num( ); i++ ) { + parms[i] = stack.A( ); + stack.Pop( 1 ); + } + + idSWFScriptVar prop = stack.A();//scope[0]->Get(propName->c_str()); + if (!prop.IsUndefined() && prop.IsObject()) + { + idSWFScriptObject * newProp = idSWFScriptObject::Alloc(); + stack.Alloc() = newProp; + newProp->DeepCopy(prop.GetObject()); + if ( newProp->HasProperty( "__constructor__" ) ) { + common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); + idSWFScriptVar instanceInit = newProp->Get( "__constructor__" ); + ( ( idSWFScriptFunction_Script * ) instanceInit.GetFunction( ) )->SetScope( *GetScope( ) ); + instanceInit.GetFunction( )->Call( newProp, parms ); + } + }else + common->Warning("Could not construct %s ",propName->c_str()); + + continue; + } + //ExecWordCode ( callsuperid ); + //ExecWordCode ( callproplex ); + //ExecWordCode ( callinterface ); + //ExecWordCode ( callsupervoid ); + ExecWordCode ( callpropvoid ); + //ExecWordCode ( sxi1 ); + //ExecWordCode ( sxi8 ); + //ExecWordCode ( sxi16 ); + //ExecWordCode ( applytype ); + //ExecWordCode ( DISABLED_pushfloat4 ); + //ExecWordCode ( newobject ); + //ExecWordCode ( newarray ); + //ExecWordCode ( newactivation ); + ExecWordCode ( newclass ); + //ExecWordCode ( getdescendants ); + //ExecWordCode ( newcatch ); + //ExecWordCode ( findpropglobalstrict ); + //ExecWordCode ( findpropglobal ); + ExecWordCode ( findpropstrict ); + //ExecWordCode ( findproperty ); + //ExecWordCode ( finddef ); + ExecWordCode ( getlex ); + InlineWordCode ( setproperty ); + { + const auto &cp = abcFile->constant_pool; + const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto &n = cp.utf8Strings[mn.nameIndex]; + + idSWFScriptVar value = stack.A( ); + stack.Pop( 1 ); + stack.A( ).GetObject( )->Set( n, value ); + continue; + } + InlineWordCode ( getlocal ) + { + stack.Alloc() = registers[bitstream.ReadEncodedU32()]; + continue; + } + //ExecWordCode ( setlocal ); + //ExecWordCode ( getglobalscope ); + ExecWordCode ( getscopeobject ); + InlineWordCode( getproperty ) { + + const auto &cp = abcFile->constant_pool; + const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto &n = cp.utf8Strings[mn.nameIndex]; + + if (!stack.A().IsObject()) + { + common->Warning("cant find property %s",n.c_str()); + stack.Pop(1); + stack.Alloc().SetUndefined(); + continue; + } + auto * obj = stack.A().GetObject(); + stack.Pop(1); + + if ( obj->HasProperty(n.c_str())) + stack.Alloc() = obj->Get(n.c_str()); + else + stack.Alloc().SetUndefined(); + + continue; + } + //ExecWordCode ( getouterscope ); + InlineWordCode ( initproperty ) + { + const auto &cp = abcFile->constant_pool; + const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto &n = cp.utf8Strings[mn.nameIndex]; + + idSWFScriptVar value = stack.A( ); + stack.Pop( 1 ); + stack.A().GetObject()->Set( n,value); + continue; + } + //ExecWordCode ( 0x69 ); + //ExecWordCode ( deleteproperty ); + //ExecWordCode ( 0x6B ); + //ExecWordCode ( getslot ); + //ExecWordCode ( setslot ); + //ExecWordCode ( getglobalslot ); + //ExecWordCode ( setglobalslot ); + //ExecWordCode ( convert_s ); + //ExecWordCode ( esc_xelem ); + //ExecWordCode ( esc_xattr ); + //ExecWordCode ( convert_i ); + //ExecWordCode ( convert_u ); + //ExecWordCode ( convert_d ); + //ExecWordCode ( convert_b ); + //ExecWordCode ( convert_o ); + //ExecWordCode ( checkfilter ); + //ExecWordCode ( DISABLED_convert ); + //ExecWordCode ( DISABLED_unplus ); + //ExecWordCode ( DISABLED_convert ); + //ExecWordCode ( coerce ); + //ExecWordCode ( coerce_b ); + //ExecWordCode ( coerce_a ); + //ExecWordCode ( coerce_i ); + //ExecWordCode ( coerce_d ); + //ExecWordCode ( coerce_s ); + //ExecWordCode ( astype ); + //ExecWordCode ( astypelate ); + //ExecWordCode ( coerce_u ); + //ExecWordCode ( coerce_o ); + //ExecWordCode ( negate ); + InlineWordCode ( increment ) + { + auto &val = stack.A( ); + idSWFScriptVar result; + switch ( val.GetType( ) ) { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( val.ToFloat() + 1.0f ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger(val.ToInteger() + 1); + continue; + default: + common->Warning( " Tried to increment incompatible type %s", val.TypeOf( )); + } + continue; + } + //ExecWordCode ( inclocal ); + //ExecWordCode ( decrement ); + //ExecWordCode ( declocal ); + //ExecWordCode ( typeof ); + //ExecWordCode ( not ); + //ExecWordCode ( bitnot ); + InlineWordCode ( add ) + { + auto & lH = stack.B(); + auto & rH = stack.A(); + idSWFScriptVar result; + switch ( lH.GetType( ) ) { + case idSWFScriptVar::SWF_VAR_STRING: + result.SetString( lH.ToString( ) + rH.ToString( ) ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + result.SetFloat( lH.ToFloat( ) + rH.ToFloat( ) ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + result.SetInteger( lH.ToInteger( ) + rH.ToInteger( ) ); + break; + case idSWFScriptVar::SWF_VAR_FUNCTION: + result.SetString( lH.ToString( ) + rH.ToString( ) ); + break; + default: + common->Warning( " Tried to add incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + } + + stack.Pop(2); + stack.Alloc() = result; + continue; + } + //ExecWordCode ( subtract ); + //ExecWordCode ( multiply ); + //ExecWordCode ( divide ); + //ExecWordCode ( modulo ); + //ExecWordCode ( lshift ); + //ExecWordCode ( rshift ); + //ExecWordCode ( urshift ); + //ExecWordCode ( bitand ); + //ExecWordCode ( bitor ); + //ExecWordCode ( bitxor ); + //ExecWordCode ( equals ); + //ExecWordCode ( strictequals ); + //ExecWordCode ( lessthan ); + //ExecWordCode ( lessequals ); + //ExecWordCode ( greaterthan ); + //ExecWordCode ( greaterequals ); + //ExecWordCode ( instanceof ); + //ExecWordCode ( istype ); + //ExecWordCode ( istypelate ); + //ExecWordCode ( in ); + //ExecWordCode ( increment_i ); + //ExecWordCode ( decrement_i ); + //ExecWordCode ( inclocal_i ); + //ExecWordCode ( declocal_i ); + //ExecWordCode ( negate_i ); + //ExecWordCode ( add_i ); + //ExecWordCode ( subtract_i ); + //ExecWordCode ( multiply_i ); + InlineWordCode ( getlocal0 ) { stack.Alloc() = registers[0]; continue;} + InlineWordCode ( getlocal1 ) { stack.Alloc() = registers[1]; continue;} + InlineWordCode ( getlocal2 ) { stack.Alloc() = registers[2]; continue;} + InlineWordCode ( getlocal3 ) { stack.Alloc() = registers[3]; continue;} + InlineWordCode ( setlocal0 ) { registers[0] = stack.A(); continue;} + InlineWordCode ( setlocal1 ) { registers[1] = stack.A(); continue;} + InlineWordCode ( setlocal2 ) { registers[2] = stack.A(); continue;} + InlineWordCode ( setlocal3 ) { registers[3] = stack.A(); continue;} + InlineWordCode ( debug ) + { + uint8 type = bitstream.ReadU8(); + uint32 index = bitstream.ReadEncodedU32(); + uint8 reg = bitstream.ReadU8(); + uint32 extra = bitstream.ReadEncodedU32(); + continue; + } + InlineWordCode ( debugline ) + InlineWordCode ( debugfile ) + uint32 nr = bitstream.ReadEncodedU32(); + continue; + //ExecWordCode ( bkptline ); + //ExecWordCode ( timestamp ); + //ExecWordCode ( restargc ); + //ExecWordCode ( restarg ); + //ExecWordCode ( codes ); + + } + } + abcCallstackLevel--; + return idSWFScriptVar( ); +} diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index a01945059f..79634d84bf 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -32,10 +32,13 @@ If you have questions concerning this license or the applicable additional terms #include "../renderer/Image.h" //#include "../../libs/rapidjson/include/rapidjson/document.h" -using namespace rapidjson; +using namespace rapidjson;//bleh #pragma warning(disable: 4355) // 'this' : used in base member initializer list + +idCVar swf_fatalVersionMismatch("swf_fatalVersionMismatch", "0", CVAR_BOOL, "Version number mismatch results in fatal error"); + #define BSWF_VERSION 16 // bumped to 16 for storing atlas image dimensions for unbuffered loads #define BSWF_MAGIC ( ( 'B' << 24 ) | ( 'S' << 16 ) | ( 'W' << 8 ) | BSWF_VERSION ) @@ -68,11 +71,13 @@ bool idSWF::LoadSWF( const char* fullpath ) return false; } - if( header.version > 9 ) - { + if ( header.version >= 9 ) { idLib::Warning( "Unsupported version %d", header.version ); - delete rawfile; - return false; + if (swf_fatalVersionMismatch.GetBool() ) + { + delete rawfile; + return false; + } } bool compressed; diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 3d98b573a1..045b430868 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -35,13 +35,83 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_loadBinary( "swf_loadBinary", "1", CVAR_INTEGER, "used to set whether to load binary swf from generated" ); +idCVar swf_printAbcObjects("swf_printAbcObjects", "1", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag"); + int idSWF::mouseX = -1; int idSWF::mouseY = -1; bool idSWF::isMouseInClientArea = false; extern idCVar in_useJoystick; +idSWFScriptObject_EventDispatcherPrototype eventDispatcherScriptObjectPrototype; + +void idSWF::CreateAbcObjects( idSWFScriptObject *globals ) +{ + //2 passes. + //1. Create all classes + int idx = 0; + for (auto & classInfo : abcFile.classes ) + { + swfInstance_info & instanceInfo = abcFile.instances[idx]; + + idSWFScriptObject * tmp = idSWFScriptObject::Alloc(); + idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; + //if these are namespace sets, concat all? + idStr fullClassName = *abcFile.constant_pool.namespaceNames[instanceInfo.name->index] + "." + abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; + idStr& superName = abcFile.constant_pool.utf8Strings[instanceInfo.super_name->nameIndex]; + //lookup prototype + if (globals->HasValidProperty(superName)) + tmp->SetPrototype(globals->GetObject(superName)->GetPrototype()); + else + common->Warning(" prototype %s not found for %s",className.c_str(),superName.c_str()); + + idSWFScriptFunction_Script * init = idSWFScriptFunction_Script::Alloc(); + init->SetData( classInfo.cinit ); + tmp->Set( "__initializer__", idSWFScriptVar( init ) ); + init->SetAbcFile(&abcFile); + idSWFScriptFunction_Script *constr = idSWFScriptFunction_Script::Alloc( ); + constr->SetData( instanceInfo.iinit ); + tmp->Set( "__constructor__", idSWFScriptVar( constr ) ); + constr->SetAbcFile(&abcFile); + globals->Set(className,tmp); + globals->Set(fullClassName,tmp); + idx++; + //check release + init->Release(); + constr->Release(); + } + idx = 0; + + //2, create all traits + for ( auto &classInfo : abcFile.classes ) { + swfInstance_info &instanceInfo = abcFile.instances[idx]; + + idStr &className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; + idSWFScriptObject *tmp = globals->GetObject( className ); + auto * target = idSWFScriptObject::Alloc( ); + auto *var = tmp->GetVariable( "[" + className + "]", true ); + + for ( swfTraits_info &trait : instanceInfo.traits ) { + target->Set( abcFile.constant_pool.utf8Strings[trait.name->nameIndex], + abcFile.GetTrait( trait, globals )->value); + } + var->value.SetObject(target); + target->Release(); + + for ( swfTraits_info &trait : classInfo.traits ) { + tmp->Set( abcFile.constant_pool.utf8Strings[trait.name->nameIndex], + abcFile.GetTrait( trait, globals )->value + ); + } + if (swf_printAbcObjects.GetBool()) + { + tmp->PrintToConsole(className.c_str()); + target->PrintToConsole("[" + className + "]"); + } + idx++; + } +} /* =================== @@ -158,7 +228,8 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, } else if( LoadSWF( filename ) ) { - WriteBinary( binaryFileName ); + if (!abcFile.class_count) + WriteBinary( binaryFileName ); } } } @@ -349,9 +420,53 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals = idSWFScriptObject::Alloc(); globals->Set( "_global", globals ); + auto *accessibilityPropertiesObj = idSWFScriptObject::Alloc( ); + //accessibilityPropertiesObj->Set( "", idSWFScriptObject::Alloc( ) ); + + auto *dispatcherObj = idSWFScriptObject::Alloc( ); + dispatcherObj->SetPrototype( &eventDispatcherScriptObjectPrototype ); + + extern idSWFScriptObject_SpriteInstancePrototype spriteInstanceScriptObjectPrototype; + auto *movieclipObj = idSWFScriptObject::Alloc( ); + movieclipObj->SetPrototype( &spriteInstanceScriptObjectPrototype ); + + if (spriteInstanceScriptObjectPrototype.GetPrototype() == NULL) + spriteInstanceScriptObjectPrototype.SetPrototype( &eventDispatcherScriptObjectPrototype ); + globals->Set( "Object", &scriptFunction_Object ); + globals->Set( "EventDispatcher", dispatcherObj ); + globals->Set( "DisplayObject", idSWFScriptObject::Alloc( ) ); + globals->Set( "InteractiveObject", idSWFScriptObject::Alloc( ) ); + globals->Set( "AccessibilityProperties", accessibilityPropertiesObj ); + globals->Set( "Dictionary", idSWFScriptObject::Alloc()); + globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); + globals->Set( "Sprite", idSWFScriptObject::Alloc( ) ); + globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); + globals->Set( "MovieClip", movieclipObj ); + + CreateAbcObjects( globals ); + bool skipInitOnContruct = symbolClasses.symbols.Num() > 0; mainspriteInstance = spriteInstanceAllocator.Alloc(); + mainspriteInstance->abcFile = &abcFile; + mainspriteInstance->scriptObject = idSWFScriptObject::Alloc( ); + //stage class. + + for ( auto &symbol : symbolClasses.symbols ) { + if ( !symbol.tag ) { + mainspriteInstance->name = symbol.name; + idStr objName; + mainspriteInstance->name.ExtractFileExtension(objName); + + auto *super = globals->Get( symbol.name ).GetObject( ); + auto dcopy = super->Get("[" + objName + "]"); + if (dcopy.IsObject()) + mainspriteInstance->scriptObject->DeepCopy( dcopy.GetObject( ) ); + + mainspriteInstance->scriptObject->SetPrototype( super ); + mainspriteInstance->scriptObject->Set( "root", mainspriteInstance->scriptObject ); + } + } mainspriteInstance->Init( mainsprite, NULL, 0 ); shortcutKeys = idSWFScriptObject::Alloc(); @@ -370,6 +485,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "getLocalString", scriptFunction_getLocalString.Bind( this ) ); globals->Set( "swapPS3Buttons", scriptFunction_swapPS3Buttons.Bind( this ) ); globals->Set( "_root", mainspriteInstance->scriptObject ); + globals->Set( "root", mainspriteInstance->scriptObject ); globals->Set( "strReplace", scriptFunction_strReplace.Bind( this ) ); globals->Set( "getCVarInteger", scriptFunction_getCVarInteger.Bind( this ) ); globals->Set( "setCVarInteger", scriptFunction_setCVarInteger.Bind( this ) ); @@ -385,22 +501,29 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "floor", scriptFunction_floor.Bind( this ) ); globals->Set( "ceil", scriptFunction_ceil.Bind( this ) ); globals->Set( "toUpper", scriptFunction_toUpper.Bind( this ) ); + globals->Set( "trace", scriptFunction_trace.Bind(this)); globals->SetNative( "platform", swfScriptVar_platform.Bind( &scriptFunction_getPlatform ) ); globals->SetNative( "blackbars", swfScriptVar_blackbars.Bind( this ) ); globals->SetNative( "cropToHeight", swfScriptVar_crop.Bind( this ) ); globals->SetNative( "cropToFit", swfScriptVar_crop.Bind( this ) ); globals->SetNative( "crop", swfScriptVar_crop.Bind( this ) ); - + // Do this to touch any external references (like sounds) // But disable script warnings because many globals won't have been created yet extern idCVar swf_debug; int debug = swf_debug.GetInteger(); swf_debug.SetInteger( 0 ); - mainspriteInstance->Run(); - mainspriteInstance->RunActions(); - mainspriteInstance->RunTo( 0 ); + + //The original impl does an initial run when contructing the stage. + //This is not possible with swf's that have the tag DoABC / run abc-bytecode + if (!skipInitOnContruct) + { + mainspriteInstance->Run(); + mainspriteInstance->RunActions(); + mainspriteInstance->RunTo( 0 ); + } swf_debug.SetInteger( debug ); @@ -988,6 +1111,12 @@ void idSWF::idSWFScriptNativeVar_crop::Set( idSWFScriptObject* object, const idS pThis->crop = value.ToBool(); } +idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call(idSWFScriptObject* thisObject, const idSWFParmList& parms) { + common->Printf("[%s] %s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", + parms[0].ToString().c_str()); + return idSWFScriptVar(); +} + // RB begin CONSOLE_COMMAND_SHIP( exportFlash, "Export all .bswf files to the exported/swf/ folder", NULL ) { diff --git a/neo/swf/SWF_PlaceObject.cpp b/neo/swf/SWF_PlaceObject.cpp index 47d81b513b..073867328e 100644 --- a/neo/swf/SWF_PlaceObject.cpp +++ b/neo/swf/SWF_PlaceObject.cpp @@ -45,6 +45,13 @@ void idSWFSpriteInstance::PlaceObject2( idSWFBitStream& bitstream ) uint64 flags = bitstream.ReadU8(); int depth = bitstream.ReadU16(); + if ( ( flags & PlaceFlagHasClassName ) != 0 ) + // idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); + + if ( ( ( ( flags & PlaceFlagHasImage ) != 0 ) && ( ( flags & PlaceFlagHasCharacter ) != 0 ) ) ) { + // idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString( ) ); + } + int characterID = -1; if( ( flags & PlaceFlagHasCharacter ) != 0 ) { @@ -146,9 +153,11 @@ void idSWFSpriteInstance::PlaceObject3( idSWFBitStream& bitstream ) uint64 flags2 = bitstream.ReadU8(); uint16 depth = bitstream.ReadU16(); - if( ( flags2 & PlaceFlagHasClassName ) != 0 || ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) - { - bitstream.ReadString(); // ignored + if ( ( flags2 & PlaceFlagHasClassName ) != 0 || ( flags1 & PlaceFlagHasClassName ) ) + //idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); + + if ( ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) { + //idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString() ); } int characterID = -1; diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index a8c6becb01..fe5ad60824 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -137,26 +137,27 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, for( int i = 0; i < parms.Num(); i++ ) { stack[ parms.Num() - i - 1 ] = parms[i]; - // Unfortunately at this point we don't have the function name anymore, so our warning messages aren't very detailed - if( i < parameters.Num() ) + if (i < parameters.Num()) { - if( parameters[i].reg > 0 && parameters[i].reg < registers.Num() ) + if (parameters[i].reg > 0 && parameters[i].reg < registers.Num()) { - registers[ parameters[i].reg ] = parms[i]; + registers[parameters[i].reg] = parms[i]; } - locals->Set( parameters[i].name, parms[i] ); + locals->Set(parameters[i].name, parms[i]); } } + // Set any additional parameters to undefined - for( int i = parms.Num(); i < parameters.Num(); i++ ) + for (int i = parms.Num(); i < parameters.Num(); i++) { - if( parameters[i].reg > 0 && parameters[i].reg < registers.Num() ) + if (parameters[i].reg > 0 && parameters[i].reg < registers.Num()) { - registers[ parameters[i].reg ].SetUndefined(); + registers[parameters[i].reg].SetUndefined(); } - locals->Set( parameters[i].name, idSWFScriptVar() ); + locals->Set(parameters[i].name, idSWFScriptVar()); } + stack.A().SetInteger( parms.Num() ); int preloadReg = 1; @@ -247,8 +248,18 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, int scopeSize = scope.Num(); scope.Append( locals ); locals->AddRef(); - - idSWFScriptVar retVal = Run( thisObject, stack, bitstream ); + idSWFScriptVar retVal; + if ( methodInfo != nullptr ) { + assert( methodInfo->body ); + auto *body = methodInfo->body; + registers[0].SetObject( thisObject ); + idSWFBitStream abcStream( methodInfo->body->code.Ptr( ), methodInfo->body->codeLength, false ); + retVal = RunAbc( thisObject, stack, abcStream ); + locals->Release( ); + locals = NULL; + return retVal; + }else + retVal = Run( thisObject, stack, bitstream ); assert( scope.Num() == scopeSize + 1 ); for( int i = scopeSize; i < scope.Num(); i++ ) diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index d310f8f215..edd9e4d655 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -28,6 +28,7 @@ If you have questions concerning this license or the applicable additional terms */ #ifndef __SWF_SCRIPTFUNCTION_H__ #define __SWF_SCRIPTFUNCTION_H__ +#include "SWF_Abc.h" /* ======================== @@ -185,7 +186,7 @@ idSWFScriptFunction_Script is a script function that's implemented in action scr class idSWFScriptFunction_Script : public idSWFScriptFunction { public: - idSWFScriptFunction_Script() : refCount( 1 ), flags( 0 ), data( NULL ), length( 0 ), prototype( NULL ), defaultSprite( NULL ) + idSWFScriptFunction_Script() : refCount( 1 ), flags( 0 ), data( NULL ), length( 0 ), prototype( NULL ), defaultSprite( NULL ), methodInfo(NULL), abcFile(NULL) { registers.SetNum( 4 ); } @@ -217,7 +218,11 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction data = _data; length = _length; } + void SetData( swfMethod_info * _method) { methodInfo = _method; } + void SetAbcFile ( SWF_AbcFile * _file ) { abcFile = _file; } + swfMethod_info * GetMethodInfo( ) { return methodInfo;} void SetScope( idList& scope ); + idList * GetScope() { return &scope; } void SetConstants( const idSWFConstantPool& _constants ) { constants.Copy( _constants ); @@ -257,10 +262,21 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction idStr CallToScript( idSWFScriptObject* thisObject, const idSWFParmList& parms, const char* filename, int characterID, int actionID ); private: + ////////////////////////////////////////////////////////////////////////// + //////////////////////ABC Wordcode Interpretation///////////////////////// + ////////////////////////////////////////////////////////////////////////// + void findpropstrict( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void getlex( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void getscopeobject( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void pushscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void popscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void getlocal0( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void newclass( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void callpropvoid( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + ////////////////////////////////////////////////////////////////////////// + idSWFScriptVar Run( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream ); - - struct ActionBlock { ActionBlock* parent = NULL; @@ -280,6 +296,9 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction idStr ExportToScript( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream, const char* filename, int characterID, int actionID ); // RB end + + idSWFScriptVar RunAbc( idSWFScriptObject * thisObject, idSWFStack & stack, idSWFBitStream & bitstream ); + SWF_AbcFile *abcFile; private: std::atomic refCount; @@ -300,7 +319,9 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction const char* name; uint8 reg; }; - idList< parmInfo_t, TAG_SWF > parameters; + idList< parmInfo_t > parameters; + + swfMethod_info *methodInfo; }; #endif // !__SWF_SCRIPTFUNCTION_H__ diff --git a/neo/swf/SWF_ScriptObject.cpp b/neo/swf/SWF_ScriptObject.cpp index ad2bf20d0a..c2e44bae78 100644 --- a/neo/swf/SWF_ScriptObject.cpp +++ b/neo/swf/SWF_ScriptObject.cpp @@ -59,6 +59,13 @@ idSWFScriptObject::swfNamedVar_t& idSWFScriptObject::swfNamedVar_t::operator=( c return *this; } +void idSWFScriptObject::DeepCopy( idSWFScriptObject *_object ) { + if ( _object != NULL ) { + for ( int i = 0; i < _object->NumVariables( ); i++ ) + Set( _object->EnumVariable( i ), _object->Get( _object->EnumVariable( i ) ) ); + } +} + /* ======================== idSWFScriptObject::idSWFScriptObject @@ -661,11 +668,15 @@ idSWFTextInstance* idSWFScriptObject::GetNestedText( const char* arg1, const cha idSWFScriptObject::PrintToConsole ======================== */ -void idSWFScriptObject::PrintToConsole() const -{ - if( variables.Num() > 0 ) - { - idLib::Printf( "%d subelements:\n", variables.Num() ); +void idSWFScriptObject::PrintToConsole(const char * name) const { + static int recursionCount = 0; + common->Printf( "------------------------------------------------------------\n" ); + + if ( variables.Num() > 0 ) { + if ( name ) + idLib::Printf( "[%s] %d subelements:\n",name, variables.Num() ); + else + idLib::Printf( "%d subelements:\n", variables.Num() ); int maxVarLength = 0; for( int i = 0; i < variables.Num(); ++i ) @@ -689,9 +700,13 @@ void idSWFScriptObject::PrintToConsole() const idLib::Printf( fmt, nv.name.c_str(), nv.value.TypeOf(), nv.value.ToString().c_str() ); } - } - else + } + else { - idLib::Printf( "No subelements\n" ); + if ( name ) + idLib::Printf( "[%s] No subelements:\n", name ); + else + idLib::Printf( "No subelements\n" ); + } } diff --git a/neo/swf/SWF_ScriptObject.h b/neo/swf/SWF_ScriptObject.h index d9a12d2cd9..a41f92e99f 100644 --- a/neo/swf/SWF_ScriptObject.h +++ b/neo/swf/SWF_ScriptObject.h @@ -140,6 +140,7 @@ class idSWFScriptObject return ( objectType == SWF_OBJECT_TEXT ) ? data.text : NULL; } + void DeepCopy( idSWFScriptObject *_object ); // Also accessible via __proto__ property idSWFScriptObject* GetPrototype() { @@ -181,18 +182,8 @@ class idSWFScriptObject idSWFSpriteInstance* GetNestedSprite( const char* arg1, const char* arg2 = NULL, const char* arg3 = NULL, const char* arg4 = NULL, const char* arg5 = NULL, const char* arg6 = NULL ); idSWFTextInstance* GetNestedText( const char* arg1, const char* arg2 = NULL, const char* arg3 = NULL, const char* arg4 = NULL, const char* arg5 = NULL, const char* arg6 = NULL ); - void PrintToConsole() const; + void PrintToConsole(const char * name = nullptr) const; -private: - std::atomic refCount; - bool noAutoDelete; - - enum swfNamedVarFlags_t - { - SWF_VAR_FLAG_NONE = 0, - SWF_VAR_FLAG_READONLY = BIT( 1 ), - SWF_VAR_FLAG_DONTENUM = BIT( 2 ) - }; struct swfNamedVar_t { swfNamedVar_t() : native( NULL ) { } @@ -206,6 +197,19 @@ class idSWFScriptObject idSWFScriptNativeVariable* native; int flags; }; + + swfNamedVar_t * GetVariable( int index, bool create ); + swfNamedVar_t * GetVariable( const char * name, bool create ); +private: + std::atomic refCount; + bool noAutoDelete; + + enum swfNamedVarFlags_t { + SWF_VAR_FLAG_NONE = 0, + SWF_VAR_FLAG_READONLY = BIT(1), + SWF_VAR_FLAG_DONTENUM = BIT(2) + }; + idList< swfNamedVar_t, TAG_SWF > variables; static const int VARIABLE_HASH_BUCKETS = 16; @@ -226,9 +230,6 @@ class idSWFScriptObject idSWFSpriteInstance* sprite; // only valid if objectType == SWF_OBJECT_SPRITE idSWFTextInstance* text; // only valid if objectType == SWF_OBJECT_TEXT } data; - - swfNamedVar_t* GetVariable( int index, bool create ); - swfNamedVar_t* GetVariable( const char* name, bool create ); }; #endif // !__SWF_SCRIPTOBJECT_H__ diff --git a/neo/swf/SWF_ScriptVar.cpp b/neo/swf/SWF_ScriptVar.cpp index 3456d4f878..13a4cffa10 100644 --- a/neo/swf/SWF_ScriptVar.cpp +++ b/neo/swf/SWF_ScriptVar.cpp @@ -51,6 +51,7 @@ idSWFScriptVar::idSWFScriptVar( const idSWFScriptVar& other ) { other.value.function->AddRef(); } + traitsInfo = other.traitsInfo; } /* diff --git a/neo/swf/SWF_ScriptVar.h b/neo/swf/SWF_ScriptVar.h index 41044dc1c3..ae2f7ab3ad 100644 --- a/neo/swf/SWF_ScriptVar.h +++ b/neo/swf/SWF_ScriptVar.h @@ -68,43 +68,19 @@ these can be on the stack, in a script object, passed around as parameters, etc they can contain raw data (int, float), strings, functions, or objects ======================== */ -class idSWFScriptVar -{ +struct swfTraits_info; +class idSWFScriptVar { public: - idSWFScriptVar() : type( SWF_VAR_UNDEF ) { } - idSWFScriptVar( const idSWFScriptVar& other ); - idSWFScriptVar( idSWFScriptObject* o ) : type( SWF_VAR_UNDEF ) - { - SetObject( o ); - } - idSWFScriptVar( idStrId s ) : type( SWF_VAR_UNDEF ) - { - SetString( s ); - } - idSWFScriptVar( const idStr& s ) : type( SWF_VAR_UNDEF ) - { - SetString( s ); - } - idSWFScriptVar( const char* s ) : type( SWF_VAR_UNDEF ) - { - SetString( idStr( s ) ); - } - idSWFScriptVar( float f ) : type( SWF_VAR_UNDEF ) - { - SetFloat( f ); - } - idSWFScriptVar( bool b ) : type( SWF_VAR_UNDEF ) - { - SetBool( b ); - } - idSWFScriptVar( int32 i ) : type( SWF_VAR_UNDEF ) - { - SetInteger( i ); - } - idSWFScriptVar( idSWFScriptFunction* nf ) : type( SWF_VAR_UNDEF ) - { - SetFunction( nf ); - } + idSWFScriptVar() : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { } + idSWFScriptVar( const idSWFScriptVar & other ); + idSWFScriptVar( idSWFScriptObject * o ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetObject( o ); } + idSWFScriptVar( idStrId s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( s ); } + idSWFScriptVar( const idStr & s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( s ); } + idSWFScriptVar( const char * s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( idStr( s ) ); } + idSWFScriptVar( float f ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetFloat( f ); } + idSWFScriptVar( bool b ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetBool( b ); } + idSWFScriptVar( int32 i ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetInteger( i ); } + idSWFScriptVar( idSWFScriptFunction * nf ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetFunction( nf ); } ~idSWFScriptVar(); idSWFScriptVar& operator=( const idSWFScriptVar& other ); @@ -272,6 +248,7 @@ class idSWFScriptVar return type; } + const swfTraits_info * traitsInfo; private: void Free(); swfScriptVarType type; diff --git a/neo/swf/SWF_ShapeParser.cpp b/neo/swf/SWF_ShapeParser.cpp index a6266236d0..eac85c6edb 100644 --- a/neo/swf/SWF_ShapeParser.cpp +++ b/neo/swf/SWF_ShapeParser.cpp @@ -31,6 +31,67 @@ If you have questions concerning this license or the applicable additional terms #pragma warning( disable: 4189 ) // local variable is initialized but not referenced +void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine &ld,swfSPMorphEdge_t & edge,bool end) +{ + + //figure out what the orientation of the cap is. + + idVec2 up = ( verts[edge.start.v0] - verts[edge.start.v1] ); + idVec2 down = ( verts[edge.end.v1] - verts[edge.end.v0] ); + idVec2 cross = idVec2( down.y, -down.x ); + idVec2 crossUp = idVec2( up.y, -up.x ); + + uint8 vertIndex; + if (end ) + vertIndex = edge.start.v1; + else + { + vertIndex = edge.start.v0; + cross = crossUp; + } + + int capCenterIdx = ld.startVerts.AddUnique( verts[vertIndex] ); + int pointCnt; + float x, z; + swfMatrix_t matrix; + float s, c; + idVec2 xup(1.0f, 0.0f ); + float angle = idMath::ATan( xup.y - cross.y, xup.x - cross.x ) + idMath::PI; + + idMath::SinCos( angle, s, c ); + float scale = ( float ) ld.style.startWidth / 40; + matrix.xx = c * scale; + matrix.yx = s * scale; + matrix.xy = -s * scale; + matrix.yy = c * scale; + int A, B; + for ( float w = 0.0; w <= 180 ; w += 10 ) { + + if ( !w ) + idMath::SinCos( DEG2RAD( w ), z, x ); + else + idMath::SinCos( DEG2RAD( w ), z, x ); + + ld.indices.Append( capCenterIdx ); + A = ld.startVerts.AddUnique( matrix.Transform( idVec2( x, z ) ) + ld.startVerts[capCenterIdx] ); + + if ( w > 10 ) { + ld.indices.Append( B ); + ld.indices.Append( A ); + ld.indices.Append( capCenterIdx ); + + }else if (w + 10 <= 180) + w+=10; + + ld.indices.Append( A ); + + + idMath::SinCos( DEG2RAD( w ), z, x ); + B = ld.startVerts.AddUnique( matrix.Transform( idVec2( x , z ) ) + ld.startVerts[capCenterIdx] ); + ld.indices.Append( B ); + } +} + /* ======================== idSWFShapeParser::ParseShape @@ -57,20 +118,43 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int ParseShapes( bitstream, NULL, false ); TriangulateSoup( shape ); + //generate triangle mesh shape.lineDraws.SetNum( lineDraws.Num() ); - for( int i = 0; i < lineDraws.Num(); i++ ) - { - idSWFShapeDrawLine& ld = shape.lineDraws[i]; - swfSPDrawLine_t& spld = lineDraws[i]; + int last = 0; + for ( int i = 0; i < lineDraws.Num(); i++ ) { + + idSWFShapeDrawLine & ld = shape.lineDraws[i]; + swfSPDrawLine_t & spld = lineDraws[i]; ld.style = spld.style; + float startWidth = ld.style.startWidth; + float endWidth = ld.style.endWidth; ld.indices.SetNum( spld.edges.Num() * 3 ); ld.indices.SetNum( 0 ); + + //edge list for( int e = 0; e < spld.edges.Num(); e++ ) { - int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] ); - ld.indices.Append( v0 ); + //startcap + if(ld.style.startCapStyle == 0 && ld.style.startWidth > 60 && spld.edges.Num()) + { + MakeCap(spld, ld, spld.edges[e], false); + } + //joint. + idVec2 up = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ); + idVec2 down = ( verts[ spld.edges[e].start.v1 ] - verts[ spld.edges[e].start.v0 ] ); + idVec2 cross = idVec2(down.y,-down.x); + idVec2 crossUp = idVec2(up.y,-up.x); + idVec2 offSetA = crossUp * ((1.0f / down.Length()) * ld.style.startWidth / 20); + idVec2 offSetB = cross * ((1.0f / down.Length()) * ld.style.startWidth / 40); + + int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetB); + int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetA + offSetB); ld.indices.Append( v0 ); - + if (spld.edges[e].start.cp == 0xFFFF) + { + ld.indices.Append(v0x); + } + int last = v0x; // Rather then tesselating curves at run time, we do them once here by inserting a vert every 10 units // It may not wind up being 10 actual pixels when rendered because the shape may have scaling applied to it if( spld.edges[e].start.cp != 0xFFFF ) @@ -79,9 +163,11 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length(); float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length(); int numPoints = 1 + idMath::Ftoi( Max( length1, length2 ) / 10.0f ); - for( int ti = 0; ti < numPoints; ti++ ) + int lastV1; + int lastV2; + for ( int ti = 0; ti < numPoints; ti++ ) { - float t0 = ( ti + 1 ) / ( ( float ) numPoints + 1.0f ); + float t0 = ( ti + 1 ) / ( (float) numPoints + 1.0f ); float t1 = ( 1.0f - t0 ); float c1 = t1 * t1; float c2 = t0 * t1 * 2.0f; @@ -91,13 +177,60 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int p1 += c2 * verts[ spld.edges[e].start.cp ]; p1 += c3 * verts[ spld.edges[e].start.v1 ]; - int v1 = ld.startVerts.AddUnique( p1 ); - ld.indices.Append( v1 ); + t0 = ( ti + 1 + 1 ) / ( ( float ) numPoints + 1.0f ); + t1 = ( 1.0f - t0 ); + c1 = t1 * t1; + c2 = t0 * t1 * 2.0f; + c3 = t0 * t0; + + idVec2 p2 = c1 * verts[spld.edges[e].start.v0]; + p2 += c2 * verts[spld.edges[e].start.cp]; + p2 += c3 * verts[spld.edges[e].start.v1]; + + idVec2 iup = p1 - p2; + idVec2 idown = p2 - p1; + idVec2 icross = idVec2( idown.y, -idown.x ); + idVec2 icrossUp = idVec2( iup.y, -iup.x ); + idVec2 ioffSetA = icrossUp * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 20 ); + idVec2 ioffSetB = icross * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 40 ); + + int v1 = ld.startVerts.AddUnique( p1 + ioffSetB ) ; + int v2 = ld.startVerts.AddUnique( p1 + ioffSetA + ioffSetB ) ; + + if (ti > 0 ) + { + ld.indices.Append( v2 ); + ld.indices.Append( lastV1 ); + } + + if (ti == 0) + { + ld.indices.Append(v2); + } ld.indices.Append( v1 ); + ld.indices.Append( v2 ); + if (ti > 0) + { + ld.indices.Append(v2); + } ld.indices.Append( v1 ); + + lastV2 = v2; + lastV1 = v1; + last = v2; } } - ld.indices.Append( ld.startVerts.AddUnique( verts[ spld.edges[e].start.v1 ] ) ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB) ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetA + offSetB) ); + ld.indices.Append( last ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB) ); + last = ld.indices.Num()-1; + + //endcap + if (ld.style.endCapStyle == 0 && ld.style.startWidth > 60) + { + MakeCap(spld, ld, spld.edges[e], true); + } } } } @@ -598,9 +731,9 @@ void idSWFShapeParser::MakeLoops() break; } } - if( shape == -1 ) + if ( shape == -1 ) { - idLib::Warning( "idSWFShapeParser: Hole not in a shape" ); + idLib::Warning( "idSWFShapeParser: Hole not in a shape, try to smoothen or straighten the erroneous shape" ); fill.loops.RemoveIndexFast( hole ); continue; } @@ -1003,12 +1136,10 @@ void idSWFShapeParser::ReadFillStyle( idSWFBitStream& bitstream ) { lineStyleCount = bitstream.ReadU16(); } - + int idx = lineDraws.Num(); lineDraws.SetNum( lineDraws.Num() + lineStyleCount ); - lineDraws.SetNum( 0 ); - for( int i = 0; i < lineStyleCount; i++ ) - { - swfLineStyle_t& lineStyle = lineDraws.Alloc().style; + for ( int i = 0; i < lineStyleCount; i++ ) { + swfLineStyle_t & lineStyle = lineDraws[idx + i].style; lineStyle.startWidth = bitstream.ReadU16(); if( lineStyle2 ) { @@ -1023,7 +1154,14 @@ void idSWFShapeParser::ReadFillStyle( idSWFBitStream& bitstream ) uint8 reserved = bitstream.ReadU( 5 ); bool noClose = bitstream.ReadBool(); uint8 endCapStyle = bitstream.ReadU( 2 ); - if( joinStyle == 2 ) + lineStyle.endCapStyle = swfLineStyle_t::capStyle(endCapStyle); + lineStyle.startCapStyle = swfLineStyle_t::capStyle(startCapStyle); + + if ( noClose ) + { + idLib::Warning("noClose was set but Ignored."); + } + if ( joinStyle == 2 ) { uint16 miterLimitFactor = bitstream.ReadU16(); } diff --git a/neo/swf/SWF_ShapeParser.h b/neo/swf/SWF_ShapeParser.h index 3ce5a00358..027c0d5dd3 100644 --- a/neo/swf/SWF_ShapeParser.h +++ b/neo/swf/SWF_ShapeParser.h @@ -36,6 +36,7 @@ This class handles parsing and triangulating a shape class idSWFShapeParser { public: + struct swfSPDrawLine_t; idSWFShapeParser() { } void Parse( idSWFBitStream& bitstream, idSWFShape& shape, int recordType ); void ParseMorph( idSWFBitStream& bitstream, idSWFShape& shape ); @@ -85,11 +86,11 @@ class idSWFShapeParser void ReadFillStyle( idSWFBitStream& bitstream ); void ParseEdge( idSWFBitStream& bitstream, int32& penX, int32& penY, swfSPEdge_t& edge ); void MakeLoops(); - void TriangulateSoup( idSWFShape& shape ); - void TriangulateSoup( idSWFFontGlyph& shape ); - int FindEarVert( const swfSPLineLoop_t& loop ); - void AddUniqueVert( idSWFShapeDrawFill& drawFill, const idVec2& start, const idVec2& end ); - + void TriangulateSoup( idSWFShape & shape ); + void TriangulateSoup( idSWFFontGlyph & shape ); + int FindEarVert( const swfSPLineLoop_t & loop ); + void AddUniqueVert( idSWFShapeDrawFill & drawFill, const idVec2 & start, const idVec2 & end ); + void MakeCap( swfSPDrawLine_t & spld, idSWFShapeDrawLine &ld , swfSPMorphEdge_t & edge,bool end); }; #endif // !__SWF_SHAPEPARSER_H__ diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 5caaf0fd67..56a6490400 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -45,6 +45,7 @@ idSWFSpriteInstance::idSWFSpriteInstance() : sprite( NULL ), parent( NULL ), depth( 0 ), + lastFrame( 0 ), itemIndex( 0 ), materialOverride( NULL ), materialWidth( 0 ), @@ -54,7 +55,10 @@ idSWFSpriteInstance::idSWFSpriteInstance() : moveToXScale( 1.0f ), moveToYScale( 1.0f ), moveToSpeed( 1.0f ), - stereoDepth( 0 ) + stereoDepth( 0 ), + actionScript( NULL ), + scriptObject ( NULL ), + constructed ( false ) { } @@ -68,21 +72,34 @@ void idSWFSpriteInstance::Init( idSWFSprite* _sprite, idSWFSpriteInstance* _pare sprite = _sprite; parent = _parent; depth = _depth; + swfMethod_info * method = nullptr; + if (actionScript && actionScript->GetMethodInfo() ) + { + method = actionScript->GetMethodInfo( ); + } + frameCount = sprite->frameCount; - scriptObject = idSWFScriptObject::Alloc(); - scriptObject->SetPrototype( &spriteInstanceScriptObjectPrototype ); + if ( !scriptObject ) + { + scriptObject = idSWFScriptObject::Alloc(); + scriptObject->SetPrototype( &spriteInstanceScriptObjectPrototype ); + + } scriptObject->SetSprite( this ); firstRun = true; - actionScript = idSWFScriptFunction_Script::Alloc(); - - idList scope; - scope.Append( sprite->swf->globals ); - scope.Append( scriptObject ); - actionScript->SetScope( scope ); + //this is already set if this is the main timeline + if ( !actionScript ) + { + actionScript = idSWFScriptFunction_Script::Alloc(); + idList scope; + scope.Append( sprite->swf->globals ); + scope.Append( scriptObject ); + actionScript->SetScope( scope ); + } actionScript->SetDefaultSprite( this ); for( int i = 0; i < sprite->doInitActions.Num(); i++ ) @@ -118,15 +135,17 @@ idSWFSpriteInstance::~idSWFSpriteInstance() idSWFSpriteInstance::FreeDisplayList ======================== */ -void idSWFSpriteInstance::FreeDisplayList() -{ - for( int i = 0; i < displayList.Num(); i++ ) - { - sprite->swf->spriteInstanceAllocator.Free( displayList[i].spriteInstance ); - sprite->swf->textInstanceAllocator.Free( displayList[i].textInstance ); +void idSWFSpriteInstance::FreeDisplayList() { + for ( int i = 0; i < displayList.Num(); i++ ) { + + if ( displayList[i].spriteInstance ) + sprite->swf->spriteInstanceAllocator.Free( displayList[i].spriteInstance ); + if ( displayList[i].textInstance ) + sprite->swf->textInstanceAllocator.Free( displayList[i].textInstance ); } displayList.SetNum( 0 ); // not calling Clear() so we don't continuously re-allocate memory currentFrame = 0; + lastFrame = 0; } /* @@ -179,12 +198,37 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte display.depth = depth; display.characterID = characterID; - idSWFDictionaryEntry* dictEntry = sprite->swf->FindDictionaryEntry( characterID ); - if( dictEntry != NULL ) - { - if( dictEntry->type == SWF_DICT_SPRITE ) + idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID ); + if ( dictEntry != NULL ) { + if (!dictEntry->resolved ) { + for ( auto &symbol : sprite->swf->symbolClasses.symbols ) { + if ( symbol.tag == characterID ) { + dictEntry->scriptClass = sprite->swf->globals->Get( symbol.name ); + dictEntry->name = &symbol.name; + break; + } + } + dictEntry->resolved = true;//dictEntry->scriptClass != nullptr; + } + + if ( dictEntry->type == SWF_DICT_SPRITE ) { display.spriteInstance = sprite->swf->spriteInstanceAllocator.Alloc(); + display.spriteInstance->abcFile = this->abcFile; + if ( dictEntry->scriptClass.IsValid() ) + { + display.spriteInstance->scriptObject = idSWFScriptObject::Alloc( ); + auto *super = dictEntry->scriptClass.GetObject( ); + + auto dcopy = super->Get("[" + *dictEntry->name + "]"); + if (dcopy.IsObject()) + { + display.spriteInstance->scriptObject->DeepCopy(dcopy.GetObject()); + } + + display.spriteInstance->scriptObject->SetPrototype( super ); + } + display.spriteInstance->Init( dictEntry->sprite, this, depth ); display.spriteInstance->RunTo( 1 ); } @@ -192,6 +236,25 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte { display.textInstance = sprite->swf->textInstanceAllocator.Alloc(); display.textInstance->Init( dictEntry->edittext, sprite->GetSWF() ); + + if ( dictEntry->scriptClass.IsValid( ) ) + { + auto *super = dictEntry->scriptClass.GetObject( ); + auto dcopy = super->Get("[" + *dictEntry->name + "]"); + if (dcopy.IsObject()) + { + display.textInstance->scriptObject.DeepCopy(dcopy.GetObject()); + } + super->SetPrototype(display.spriteInstance->scriptObject->GetPrototype() ); + display.spriteInstance->scriptObject->SetPrototype( super ); + } + + + //display.textInstance->scriptObject.Set( "onPress", "a" ); + } else if ( dictEntry->type == SWF_DICT_TEXT ) + { + //display.textInstance = sprite->swf->textInstanceAllocator.Alloc( ); + //display.textInstance->Init( dictEntry->text, sprite->GetSWF( ) ); } } return &display; @@ -202,13 +265,13 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte idSWFSpriteInstance::RemoveDisplayEntry ======================== */ -void idSWFSpriteInstance::RemoveDisplayEntry( int depth ) -{ - swfDisplayEntry_t* entry = FindDisplayEntry( depth ); - if( entry != NULL ) - { - sprite->swf->spriteInstanceAllocator.Free( entry->spriteInstance ); - sprite->swf->textInstanceAllocator.Free( entry->textInstance ); +void idSWFSpriteInstance::RemoveDisplayEntry( int depth ) { + swfDisplayEntry_t * entry = FindDisplayEntry( depth ); + if ( entry != NULL ) { + if ( entry->spriteInstance ) + sprite->swf->spriteInstanceAllocator.Free( entry->spriteInstance ); + if (entry->textInstance ) + sprite->swf->textInstanceAllocator.Free( entry->textInstance ); displayList.RemoveIndex( displayList.IndexOf( entry ) ); } } @@ -314,11 +377,26 @@ bool idSWFSpriteInstance::RunActions() actions.SetNum( 0 ); return false; } + + if (!constructed) { + if (scriptObject->HasProperty("__constructor__")) { + common->DPrintf("Calling constructor for %s%\n", name.c_str()); + idSWFScriptVar instanceInit = scriptObject->Get("__constructor__"); + if (!((idSWFScriptFunction_Script*)instanceInit.GetFunction())->GetScope()->Num()) + ((idSWFScriptFunction_Script*)instanceInit.GetFunction())->SetScope(*actionScript->GetScope()); + instanceInit.GetFunction()->Call(scriptObject, idSWFParmList()); + constructed = true; + } + } + - if( firstRun && scriptObject->HasProperty( "onLoad" ) ) + if(firstRun && !scriptObject->HasProperty("__eventDispatcher__") && scriptObject->HasProperty( "onLoad" ) ) { firstRun = false; - idSWFScriptVar onLoad = scriptObject->Get( "onLoad" ); + idSWFScriptVar onLoad = scriptObject->Get("onLoad"); + if (!((idSWFScriptFunction_Script*)onLoad.GetFunction())->GetScope()->Num()) + ((idSWFScriptFunction_Script*)onLoad.GetFunction())->GetScope()->Append(sprite->swf->globals); + onLoad.GetFunction()->Call( scriptObject, idSWFParmList() ); } @@ -349,6 +427,52 @@ bool idSWFSpriteInstance::RunActions() } } + if (firstRun && scriptObject->HasProperty("__eventDispatcher__")) { + firstRun = false; + idSWFScriptObject* eventDispatcher = scriptObject->Get("__eventDispatcher__").GetObject(); + idSWFScriptVar var = eventDispatcher->Get("addedToStage"); + if (var.IsFunction()) + { + + idSWFScriptObject* eventObj = sprite->swf->globals + ->Get("EventDispatcher").GetObject() + ->Get("Event").GetObject() + ->Get("[Event]").GetObject(); + + idSWFScriptVar eventParm; + eventParm.SetObject(idSWFScriptObject::Alloc()); + eventParm.GetObject()->DeepCopy(eventObj); + + idSWFScriptVar eventArg; + eventArg.SetObject(idSWFScriptObject::Alloc()); + eventArg.GetObject()->Set("Event", eventParm); + + idSWFParmList parms; + parms.Append(eventArg); + if (!((idSWFScriptFunction_Script*)var.GetFunction())->GetScope()->Num()) + ((idSWFScriptFunction_Script*)var.GetFunction())->GetScope()->Append(sprite->swf->globals); + var.GetFunction()->Call(scriptObject, parms); + parms.Clear(); + } + } + + //do frame scripts. + if (currentFrame && currentFrame != lastFrame && isPlaying) + { + idStr frameId = idStr("frame") + idStr(currentFrame); + idSWFScriptObject* obj = scriptObject; + if (obj && obj->HasValidProperty(frameId.c_str())) { + idSWFScriptVar frameFunc = obj->Get(frameId.c_str()); + if (frameFunc.IsFunction()) { + idSWFScriptFunction* funcPtr = frameFunc.GetFunction(); + if (!((idSWFScriptFunction_Script*)funcPtr)->GetScope()->Num()) + ((idSWFScriptFunction_Script*)funcPtr)->SetScope(*actionScript->GetScope()); + funcPtr->Call(obj, idSWFParmList()); + } + } + } + + firstRun = false; return true; } @@ -457,7 +581,7 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) idLib::Printf( "Run Sprite: Unhandled tag %s\n", idSWF::GetTagName( command.tag ) ); } } - + lastFrame = currentFrame; currentFrame = targetFrame; } @@ -1024,8 +1148,9 @@ idSWFScriptObject_SpriteInstancePrototype #define SWF_SPRITE_FUNCTION_SET( x ) scriptFunction_##x.AddRef(); Set( #x, &scriptFunction_##x ); #define SWF_SPRITE_NATIVE_VAR_SET( x ) SetNative( #x, &swfScriptVar_##x ); -idSWFScriptObject_SpriteInstancePrototype::idSWFScriptObject_SpriteInstancePrototype() +idSWFScriptObject_SpriteInstancePrototype::idSWFScriptObject_SpriteInstancePrototype() { + SWF_SPRITE_FUNCTION_SET( addFrameScript ); SWF_SPRITE_FUNCTION_SET( duplicateMovieClip ); SWF_SPRITE_FUNCTION_SET( gotoAndPlay ); SWF_SPRITE_FUNCTION_SET( gotoAndStop ); @@ -1046,6 +1171,7 @@ idSWFScriptObject_SpriteInstancePrototype::idSWFScriptObject_SpriteInstanceProto SWF_SPRITE_NATIVE_VAR_SET( _height ); SWF_SPRITE_NATIVE_VAR_SET( _rotation ); SWF_SPRITE_NATIVE_VAR_SET( _name ); + SWF_SPRITE_NATIVE_VAR_SET( name ); SWF_SPRITE_NATIVE_VAR_SET( _currentframe ); SWF_SPRITE_NATIVE_VAR_SET( _totalframes ); SWF_SPRITE_NATIVE_VAR_SET( _target ); @@ -1111,8 +1237,16 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _height ) } SWF_SPRITE_NATIVE_VAR_DEFINE_SET( _height ) { } -SWF_SPRITE_FUNCTION_DEFINE( duplicateMovieClip ) + +SWF_SPRITE_FUNCTION_DEFINE( addFrameScript ) { + SWF_SPRITE_PTHIS_FUNC( "addFrameScript" ); + common->Printf("Have to add AddFrame script for frame %i\n" , parms[1].ToInteger()); + return idSWFScriptVar(); +} + + +SWF_SPRITE_FUNCTION_DEFINE( duplicateMovieClip ) { SWF_SPRITE_PTHIS_FUNC( "duplicateMovieClip" ); if( pThis->parent == NULL ) @@ -1499,6 +1633,12 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _name ) return pThis->name.c_str(); } +SWF_SPRITE_NATIVE_VAR_DEFINE_GET( name ) +{ + SWF_SPRITE_PTHIS_GET("name"); + return pThis->name.c_str(); +} + SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _currentframe ) { SWF_SPRITE_PTHIS_GET( "_currentframe" ); diff --git a/neo/swf/SWF_SpriteInstance.h b/neo/swf/SWF_SpriteInstance.h index 1fbb3098f9..3a147274ca 100644 --- a/neo/swf/SWF_SpriteInstance.h +++ b/neo/swf/SWF_SpriteInstance.h @@ -147,9 +147,11 @@ class idSWFSpriteInstance bool childrenRunning; bool firstRun; + bool constructed; // currentFrame is the frame number currently in the displayList // we use 1 based frame numbers because currentFrame = 0 means nothing is in the display list // it's also convenient because Flash also uses 1 based frame numbers + uint16 lastFrame; uint16 currentFrame; uint16 frameCount; @@ -184,6 +186,7 @@ class idSWFSpriteInstance idList< swfDisplayEntry_t, TAG_SWF > displayList; swfDisplayEntry_t* FindDisplayEntry( int depth ); + SWF_AbcFile * abcFile; // name of this sprite instance idStr name; @@ -258,6 +261,7 @@ class idSWFScriptObject_SpriteInstancePrototype : public idSWFScriptObject idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ } scriptFunction_##x + SWF_SPRITE_FUNCTION_DECLARE( addFrameScript ); SWF_SPRITE_FUNCTION_DECLARE( duplicateMovieClip ); SWF_SPRITE_FUNCTION_DECLARE( gotoAndPlay ); SWF_SPRITE_FUNCTION_DECLARE( gotoAndStop ); @@ -279,6 +283,7 @@ class idSWFScriptObject_SpriteInstancePrototype : public idSWFScriptObject SWF_NATIVE_VAR_DECLARE( _rotation ); SWF_NATIVE_VAR_DECLARE_READONLY( _name ); + SWF_NATIVE_VAR_DECLARE_READONLY( name ); SWF_NATIVE_VAR_DECLARE_READONLY( _currentframe ); SWF_NATIVE_VAR_DECLARE_READONLY( _totalframes ); SWF_NATIVE_VAR_DECLARE_READONLY( _target ); diff --git a/neo/swf/SWF_Sprites.cpp b/neo/swf/SWF_Sprites.cpp index 563ad8913a..fca27a3411 100644 --- a/neo/swf/SWF_Sprites.cpp +++ b/neo/swf/SWF_Sprites.cpp @@ -129,6 +129,8 @@ void idSWFSprite::Load( idSWFBitStream& bitstream, bool parseDictionary ) HANDLE_SWF_TAG( DefineText ); HANDLE_SWF_TAG( DefineText2 ); HANDLE_SWF_TAG( DefineEditText ); + HANDLE_SWF_TAG( DoABC ); + HANDLE_SWF_TAG( SymbolClass ); #undef HANDLE_SWF_TAG default: handled = false; diff --git a/neo/swf/SWF_TextInstance.cpp b/neo/swf/SWF_TextInstance.cpp index 92fc00dc05..eea6cf7cec 100644 --- a/neo/swf/SWF_TextInstance.cpp +++ b/neo/swf/SWF_TextInstance.cpp @@ -68,6 +68,80 @@ idSWFTextInstance::~idSWFTextInstance() subtitleTimingInfo.Clear(); } +void idSWFTextInstance::Init( idSWFText * _text, idSWF * _swf ) +{ + editText = nullptr; + staticText = _text; + swf = _swf; + + text = "staticText";//idLocalization::GetString( staticText->textRecords[0]. ); + + lengthCalculated = false; + //if ( editText ) + //{ + // variable = editText->variable; + // color = editText->color; + //} + visible = true; + + selectionStart = -1; + selectionEnd = -1; + + scroll = 0; + scrollTime = 0; + maxscroll = 0; + maxLines = 0; + linespacing = 0; + glyphScale = 1.0f; + + shiftHeld = false; + tooltip = false; + renderMode = SWF_TEXT_RENDER_NORMAL; + generatingText = false; + triggerGenerate = false; + rndSpotsVisible = 0; + textSpotsVisible = 0; + startRndTime = 0; + charMultiplier = 0; + prevReplaceIndex = 0; + scrollUpdate = false; + ignoreColor = false; + + isSubtitle = false; + subLength = 0; + subAlign = 0; + subUpdating = false; + subCharStartIndex = 0; + subNextStartIndex = 0; + subCharEndIndex = 0; + subDisplayTime = 0; + subStartTime = -1; + subSourceID = -1; + subNeedsSwitch = false; + subForceKill = false; + subKillTimeDelay = 0; + subSwitchTime = 0; + subLastWordIndex = 0; + subPrevLastWordIndex = 0; + subInitialLine = true; + + textLength = 0; + + inputTextStartChar = 0; + + renderDelay = swf_textRndLetterDelay.GetInteger( ); + needsSoundUpdate = false; + useDropShadow = false; + useStroke = false; + strokeStrength = 1.0f; + strokeWeight = swf_textStrokeSize.GetFloat( ); + + scriptObject.SetPrototype( &textInstanceScriptObjectPrototype ); + scriptObject.SetText( this ); + scriptObject.SetNoAutoDelete( true ); + +} + /* ======================== idSWFTextInstance::Init diff --git a/neo/swf/SWF_TextInstance.h b/neo/swf/SWF_TextInstance.h index 8e61fc32e7..6af7cda49e 100644 --- a/neo/swf/SWF_TextInstance.h +++ b/neo/swf/SWF_TextInstance.h @@ -47,7 +47,8 @@ class idSWFTextInstance idSWFTextInstance(); ~idSWFTextInstance(); - void Init( idSWFEditText* editText, idSWF* _swf ); + void Init( idSWFEditText * _editText, idSWF * _swf ); + void Init( idSWFText * _text, idSWF *_swf ); idSWFScriptObject* GetScriptObject() { @@ -175,13 +176,16 @@ class idSWFTextInstance lengthCalculated = false; } + const idSWFText * GetText() const { return staticText; } + // Removing the private access control statement due to cl 214702 // Apparently MS's C++ compiler supports the newer C++ standard, and GCC supports C++03 // In the new C++ standard, nested members of a friend class have access to private/protected members of the class granting friendship // In C++03, nested members defined in a friend class do NOT have access to private/protected members of the class granting friendship - idSWFEditText* editText; - idSWF* swf; + idSWFEditText * editText; + idSWFText * staticText; + idSWF * swf; // this text instance's script object idSWFScriptObject scriptObject; diff --git a/neo/swf/SWF_Types.h b/neo/swf/SWF_Types.h index 65b8051a12..5b13c7b654 100644 --- a/neo/swf/SWF_Types.h +++ b/neo/swf/SWF_Types.h @@ -162,6 +162,9 @@ struct swfLineStyle_t uint16 endWidth; swfColorRGBA_t startColor; swfColorRGBA_t endColor; + uint8 startCapStyle; + uint8 endCapStyle; + enum capStyle { round = 0,none,square }; }; struct swfGradientRecord_t { diff --git a/neo/swf/opcodes.tbl b/neo/swf/opcodes.tbl new file mode 100644 index 0000000000..ab58bc8402 --- /dev/null +++ b/neo/swf/opcodes.tbl @@ -0,0 +1,297 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +/* + * Includers must define an ABC_OP and ABC_UNUSED_OP macros of the following form: + * + * #define ABC_OP(opCount, throw, stack, internal, name) ... // defines regular op code + * #define ABC_UNUSED_OP(opCount, throw, stack, internal, name) ... // defines unused op code + * + * Selected arguments can then be used within the macro expansions. + * - opCount Number of operands encoded in the instruction. Uses -1 for "invalid", we can avoid that if necessary + * - throw 1 if the operation can throw, 0 otherwise + * - stack Stack movement not taking into account run-time names or function arguments + * - internal 1 if the operation is internal to the VM, 0 otherwise + * - name Unquoted name of operation. + * + * There MUST be exactly 256 entries in this table. + * The location of an opcode definition in this table determines its hex value, which is + * what must correspond to what is read out of the ABC file. + * Entries should never be added or removed from this table. New abc instructions may be added + * by updating entries for unused op codes. Unused op codes have a "name" that is a hex value. + * + */ +//-------------------------------------------------------------------------------------------------------- +#ifndef ABC_OP_F +# ifdef VMCFG_FLOAT +# define ABC_OP_F ABC_OP +# else +# define ABC_OP_F(o,t,s,i,n) ABC_UNUSED_OP(-1, 0, 0, 0, DISABLED_##n) +# endif +# define ABC_OP_F_DEFINED +#endif + +// opCount throw stack internal name hex +ABC_UNUSED_OP( -1, 0, 0, 0, 0x00) // 0x00 +ABC_OP( 0, 0, 0, 0, bkpt) // 0x01 +ABC_OP( 0, 0, 0, 0, nop) // 0x02 +ABC_OP( 0, 1, -1, 0, throw) // 0x03 +ABC_OP( 1, 1, 0, 0, getsuper) // 0x04 +ABC_OP( 1, 1, -2, 0, setsuper) // 0x05 +ABC_OP( 1, 1, 0, 0, dxns) // 0x06 +ABC_OP( 0, 1, -1, 0, dxnslate) // 0x07 +ABC_OP( 1, 0, 0, 0, kill) // 0x08 +ABC_OP( 0, 0, 0, 0, label) // 0x09 +ABC_OP_F( 0, 1, 0, 0, lf32x4) // 0x0A +ABC_OP_F( 0, 1, -2, 0, sf32x4) // 0x0B +ABC_OP( 1, 1, -2, 0, ifnlt) // 0x0C +ABC_OP( 1, 1, -2, 0, ifnle) // 0x0D +ABC_OP( 1, 1, -2, 0, ifngt) // 0x0E +ABC_OP( 1, 1, -2, 0, ifnge) // 0x0F +ABC_OP( 1, 0, 0, 0, jump) // 0x10 +ABC_OP( 1, 0, -1, 0, iftrue) // 0x11 +ABC_OP( 1, 0, -1, 0, iffalse) // 0x12 +ABC_OP( 1, 1, -2, 0, ifeq) // 0x13 +ABC_OP( 1, 1, -2, 0, ifne) // 0x14 +ABC_OP( 1, 1, -2, 0, iflt) // 0x15 +ABC_OP( 1, 1, -2, 0, ifle) // 0x16 +ABC_OP( 1, 1, -2, 0, ifgt) // 0x17 +ABC_OP( 1, 1, -2, 0, ifge) // 0x18 +ABC_OP( 1, 0, -2, 0, ifstricteq) // 0x19 +ABC_OP( 1, 0, -2, 0, ifstrictne) // 0x1A +ABC_OP( 2, 0, -1, 0, lookupswitch) // 0x1B +ABC_OP( 0, 1, -1, 0, pushwith) // 0x1C +ABC_OP( 0, 0, 0, 0, popscope) // 0x1D +ABC_OP( 0, 1, -1, 0, nextname) // 0x1E +ABC_OP( 0, 1, -1, 0, hasnext) // 0x1F +ABC_OP( 0, 0, 1, 0, pushnull) // 0x20 +ABC_OP( 0, 0, 1, 0, pushundefined) // 0x21 +ABC_OP_F( 1, 0, 1, 0, pushfloat) // 0x22 +ABC_OP( 0, 1, -1, 0, nextvalue) // 0x23 +ABC_OP( 1, 0, 1, 0, pushbyte) // 0x24 +ABC_OP( 1, 0, 1, 0, pushshort) // 0x25 +ABC_OP( 0, 0, 1, 0, pushtrue) // 0x26 +ABC_OP( 0, 0, 1, 0, pushfalse) // 0x27 +ABC_OP( 0, 0, 1, 0, pushnan) // 0x28 +ABC_OP( 0, 0, -1, 0, pop) // 0x29 +ABC_OP( 0, 0, 1, 0, dup) // 0x2A +ABC_OP( 0, 0, 0, 0, swap) // 0x2B +ABC_OP( 1, 0, 1, 0, pushstring) // 0x2C +ABC_OP( 1, 0, 1, 0, pushint) // 0x2D +ABC_OP( 1, 0, 1, 0, pushuint) // 0x2E +ABC_OP( 1, 0, 1, 0, pushdouble) // 0x2F +ABC_OP( 0, 1, -1, 0, pushscope) // 0x30 +ABC_OP( 1, 0, 1, 0, pushnamespace) // 0x31 +ABC_OP( 2, 1, 1, 0, hasnext2) // 0x32 +ABC_OP( -1, 1, 0, 1, lix8) // 0x33 +ABC_OP( -1, 1, 0, 1, lix16) // 0x34 +ABC_OP( 0, 1, 0, 0, li8) // 0x35 +ABC_OP( 0, 1, 0, 0, li16) // 0x36 +ABC_OP( 0, 1, 0, 0, li32) // 0x37 +ABC_OP( 0, 1, 0, 0, lf32) // 0x38 +ABC_OP( 0, 1, 0, 0, lf64) // 0x39 +ABC_OP( 0, 1, -2, 0, si8) // 0x3A +ABC_OP( 0, 1, -2, 0, si16) // 0x3B +ABC_OP( 0, 1, -2, 0, si32) // 0x3C +ABC_OP( 0, 1, -2, 0, sf32) // 0x3D +ABC_OP( 0, 1, -2, 0, sf64) // 0x3E +ABC_UNUSED_OP( -1, 0, 0, 0, 0x3F) // 0x3F +ABC_OP( 1, 1, 1, 0, newfunction) // 0x40 +ABC_OP( 1, 1, -1, 0, call) // 0x41 +ABC_OP( 1, 1, 0, 0, construct) // 0x42 +ABC_OP( 2, 1, 0, 0, callmethod) // 0x43 +ABC_OP( 2, 1, 0, 0, callstatic) // 0x44 +ABC_OP( 2, 1, 0, 0, callsuper) // 0x45 +ABC_OP( 2, 1, 0, 0, callproperty) // 0x46 +ABC_OP( 0, 0, 0, 0, returnvoid) // 0x47 +ABC_OP( 0, 1, -1, 0, returnvalue) // 0x48 +ABC_OP( 1, 1, -1, 0, constructsuper) // 0x49 +ABC_OP( 2, 1, 0, 0, constructprop) // 0x4A +ABC_OP( -1, 1, 0, 1, callsuperid) // 0x4B +ABC_OP( 2, 1, 0, 0, callproplex) // 0x4C +ABC_OP( -1, 1, 0, 1, callinterface) // 0x4D +ABC_OP( 2, 1, -1, 0, callsupervoid) // 0x4E +ABC_OP( 2, 1, -1, 0, callpropvoid) // 0x4F +ABC_OP( 0, 1, 0, 0, sxi1) // 0x50 +ABC_OP( 0, 1, 0, 0, sxi8) // 0x51 +ABC_OP( 0, 1, 0, 0, sxi16) // 0x52 +ABC_OP( 1, 1, 0, 0, applytype) // 0x53 +ABC_OP_F( 1, 0, 1, 0, pushfloat4) // 0x54 +ABC_OP( 1, 1, 1, 0, newobject) // 0x55 +ABC_OP( 1, 1, 1, 0, newarray) // 0x56 +ABC_OP( 0, 1, 1, 0, newactivation) // 0x57 +ABC_OP( 1, 1, 0, 0, newclass) // 0x58 +ABC_OP( 1, 1, 0, 0, getdescendants) // 0x59 +ABC_OP( 1, 1, 1, 0, newcatch) // 0x5A +ABC_OP( -1, 1, 0, 1, findpropglobalstrict) // 0x5B +ABC_OP( -1, 1, 0, 1, findpropglobal) // 0x5C +ABC_OP( 1, 1, 1, 0, findpropstrict) // 0x5D +ABC_OP( 1, 1, 1, 0, findproperty) // 0x5E +ABC_OP( 1, 1, 1, 0, finddef) // 0x5F +ABC_OP( 1, 1, 1, 0, getlex) // 0x60 +ABC_OP( 1, 1, -2, 0, setproperty) // 0x61 +ABC_OP( 1, 0, 1, 0, getlocal) // 0x62 +ABC_OP( 1, 0, -1, 0, setlocal) // 0x63 +ABC_OP( 0, 0, 1, 0, getglobalscope) // 0x64 +ABC_OP( 1, 0, 1, 0, getscopeobject) // 0x65 +ABC_OP( 1, 1, 0, 0, getproperty) // 0x66 +ABC_OP( 1, 0, 1, 0, getouterscope) // 0x67 +ABC_OP( 1, 1, -2, 0, initproperty) // 0x68 +ABC_UNUSED_OP( -1, 0, 0, 0, 0x69) // 0x69 +ABC_OP( 1, 1, 0, 0, deleteproperty) // 0x6A +ABC_UNUSED_OP( -1, 0, 0, 0, 0x6B) // 0x6B +ABC_OP( 1, 1, 0, 0, getslot) // 0x6C +ABC_OP( 1, 1, -2, 0, setslot) // 0x6D +ABC_OP( 1, 0, 1, 0, getglobalslot) // 0x6E +ABC_OP( 1, 1, -1, 0, setglobalslot) // 0x6F +ABC_OP( 0, 1, 0, 0, convert_s) // 0x70 +ABC_OP( 0, 1, 0, 0, esc_xelem) // 0x71 +ABC_OP( 0, 1, 0, 0, esc_xattr) // 0x72 +ABC_OP( 0, 1, 0, 0, convert_i) // 0x73 +ABC_OP( 0, 1, 0, 0, convert_u) // 0x74 +ABC_OP( 0, 1, 0, 0, convert_d) // 0x75 +ABC_OP( 0, 1, 0, 0, convert_b) // 0x76 +ABC_OP( 0, 1, 0, 0, convert_o) // 0x77 +ABC_OP( 0, 1, 0, 0, checkfilter) // 0x78 +ABC_OP_F( 0, 1, 0, 0, convert_f) // 0x79 +ABC_OP_F( 0, 1, 0, 0, unplus) // 0x7A +ABC_OP_F( 0, 1, 0, 0, convert_f4) // 0x7B +ABC_UNUSED_OP( -1, 0, 0, 0, 0x7C) // 0x7C +ABC_UNUSED_OP( -1, 0, 0, 0, 0x7D) // 0x7D +ABC_UNUSED_OP( -1, 0, 0, 0, 0x7E) // 0x7E +ABC_UNUSED_OP( -1, 0, 0, 0, 0x7F) // 0x7F +ABC_OP( 1, 1, 0, 0, coerce) // 0x80 +ABC_OP( 0, 1, 0, 0, coerce_b) // 0x81 +ABC_OP( 0, 1, 0, 0, coerce_a) // 0x82 +ABC_OP( 0, 1, 0, 0, coerce_i) // 0x83 +ABC_OP( 0, 1, 0, 0, coerce_d) // 0x84 +ABC_OP( 0, 1, 0, 0, coerce_s) // 0x85 +ABC_OP( 1, 1, 0, 0, astype) // 0x86 +ABC_OP( 0, 1, -1, 0, astypelate) // 0x87 +ABC_OP( 0, 1, 0, 0, coerce_u) // 0x88 +ABC_OP( 0, 1, 0, 0, coerce_o) // 0x89 +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8A) // 0x8A +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8B) // 0x8B +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8C) // 0x8C +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8D) // 0x8D +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8E) // 0x8E +ABC_UNUSED_OP( -1, 0, 0, 0, 0x8F) // 0x8F +ABC_OP( 0, 1, 0, 0, negate) // 0x90 +ABC_OP( 0, 1, 0, 0, increment) // 0x91 +ABC_OP( 1, 1, 0, 0, inclocal) // 0x92 +ABC_OP( 0, 1, 0, 0, decrement) // 0x93 +ABC_OP( 1, 1, 0, 0, declocal) // 0x94 +ABC_OP( 0, 0, 0, 0, typeof) // 0x95 +ABC_OP( 0, 0, 0, 0, not) // 0x96 +ABC_OP( 0, 1, 0, 0, bitnot) // 0x97 +ABC_UNUSED_OP( -1, 0, 0, 0, 0x98) // 0x98 +ABC_UNUSED_OP( -1, 0, 0, 0, 0x99) // 0x99 +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9A) // 0x9A +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9B) // 0x9B +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9C) // 0x9C +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9D) // 0x9D +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9E) // 0x9E +ABC_UNUSED_OP( -1, 0, 0, 0, 0x9F) // 0x9F +ABC_OP( 0, 1, -1, 0, add) // 0xA0 +ABC_OP( 0, 1, -1, 0, subtract) // 0xA1 +ABC_OP( 0, 1, -1, 0, multiply) // 0xA2 +ABC_OP( 0, 1, -1, 0, divide) // 0xA3 +ABC_OP( 0, 1, -1, 0, modulo) // 0xA4 +ABC_OP( 0, 1, -1, 0, lshift) // 0xA5 +ABC_OP( 0, 1, -1, 0, rshift) // 0xA6 +ABC_OP( 0, 1, -1, 0, urshift) // 0xA7 +ABC_OP( 0, 1, -1, 0, bitand) // 0xA8 +ABC_OP( 0, 1, -1, 0, bitor) // 0xA9 +ABC_OP( 0, 1, -1, 0, bitxor) // 0xAA +ABC_OP( 0, 1, -1, 0, equals) // 0xAB +ABC_OP( 0, 1, -1, 0, strictequals) // 0xAC +ABC_OP( 0, 1, -1, 0, lessthan) // 0xAD +ABC_OP( 0, 1, -1, 0, lessequals) // 0xAE +ABC_OP( 0, 1, -1, 0, greaterthan) // 0xAF +ABC_OP( 0, 1, -1, 0, greaterequals) // 0xB0 +ABC_OP( 0, 1, -1, 0, instanceof) // 0xB1 +ABC_OP( 1, 1, 0, 0, istype) // 0xB2 +ABC_OP( 0, 1, -1, 0, istypelate) // 0xB3 +ABC_OP( 0, 1, -1, 0, in) // 0xB4 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xB5) // 0xB5 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xB6) // 0xB6 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xB7) // 0xB7 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xB8) // 0xB8 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xB9) // 0xB9 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBA) // 0xBA +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBB) // 0xBB +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBC) // 0xBC +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBD) // 0xBD +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBE) // 0xBE +ABC_UNUSED_OP( -1, 0, 0, 0, 0xBF) // 0xBF +ABC_OP( 0, 1, 0, 0, increment_i) // 0xC0 +ABC_OP( 0, 1, 0, 0, decrement_i) // 0xC1 +ABC_OP( 1, 1, 0, 0, inclocal_i) // 0xC2 +ABC_OP( 1, 1, 0, 0, declocal_i) // 0xC3 +ABC_OP( 0, 1, 0, 0, negate_i) // 0xC4 +ABC_OP( 0, 1, -1, 0, add_i) // 0xC5 +ABC_OP( 0, 1, -1, 0, subtract_i) // 0xC6 +ABC_OP( 0, 1, -1, 0, multiply_i) // 0xC7 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xC8) // 0xC8 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xC9) // 0xC9 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCA) // 0xCA +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCB) // 0xCB +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCC) // 0xCC +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCD) // 0xCD +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCE) // 0xCE +ABC_UNUSED_OP( -1, 0, 0, 0, 0xCF) // 0xCF +ABC_OP( 0, 0, 1, 0, getlocal0) // 0xD0 +ABC_OP( 0, 0, 1, 0, getlocal1) // 0xD1 +ABC_OP( 0, 0, 1, 0, getlocal2) // 0xD2 +ABC_OP( 0, 0, 1, 0, getlocal3) // 0xD3 +ABC_OP( 0, 0, -1, 0, setlocal0) // 0xD4 +ABC_OP( 0, 0, -1, 0, setlocal1) // 0xD5 +ABC_OP( 0, 0, -1, 0, setlocal2) // 0xD6 +ABC_OP( 0, 0, -1, 0, setlocal3) // 0xD7 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xD8) // 0xD8 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xD9) // 0xD9 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDA) // 0xDA +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDB) // 0xDB +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDC) // 0xDC +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDD) // 0xDD +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDE) // 0xDE +ABC_UNUSED_OP( -1, 0, 0, 0, 0xDF) // 0xDF +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE0) // 0xE0 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE1) // 0xE1 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE2) // 0xE2 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE3) // 0xE3 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE4) // 0xE4 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE5) // 0xE5 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE6) // 0xE6 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE7) // 0xE7 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE8) // 0xE8 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xE9) // 0xE9 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xEA) // 0xEA +ABC_UNUSED_OP( -1, 0, 0, 0, 0xEB) // 0xEB +ABC_UNUSED_OP( -1, 0, 0, 0, 0xEC) // 0xEC +ABC_UNUSED_OP( -1, 0, 0, 0, 0xED) // 0xED +ABC_UNUSED_OP( -1, 0, 0, 0, 0xEE) // 0xEE - was OP_abs_jump +ABC_OP( 4, 1, 0, 0, debug) // 0xEF +ABC_OP( 1, 1, 0, 0, debugline) // 0xF0 +ABC_OP( 1, 1, 0, 0, debugfile) // 0xF1 +ABC_OP( 1, 0, 0, 0, bkptline) // 0xF2 +ABC_OP( 0, 0, 0, 0, timestamp) // 0xF3 +ABC_OP( -1, 1, 0, 1, restargc) // 0xF4 +ABC_OP( -1, 1, 0, 1, restarg) // 0xF5 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xF6) // 0xF6 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xF7) // 0xF7 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xF8) // 0xF8 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xF9) // 0xF9 +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFA) // 0xFA +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFB) // 0xFB +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFC) // 0xFC +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFD) // 0xFD +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFE) // 0xFE +ABC_UNUSED_OP( -1, 0, 0, 0, 0xFF) // 0xFF +#ifdef ABC_OP_F_DEFINED +# undef ABC_OP_F +# undef ABC_OP_F_DEFINED +#endif From 5850993755af52da60db971d1c3679a147f9f0ab Mon Sep 17 00:00:00 2001 From: HarrievG Date: Sun, 19 Feb 2023 14:31:24 +0100 Subject: [PATCH 02/20] A-Style --- neo/swf/SWF.h | 9 +- neo/swf/SWF_Abc.cpp | 931 +++++++++++---------- neo/swf/SWF_Abc.h | 73 +- neo/swf/SWF_Bitstream.h | 9 +- neo/swf/SWF_Dictionary.cpp | 2 +- neo/swf/SWF_Enums.h | 2 +- neo/swf/SWF_EventDispatcher.cpp | 45 +- neo/swf/SWF_EventDispatcher.h | 3 +- neo/swf/SWF_Events.cpp | 179 +++-- neo/swf/SWF_Interpreter.cpp | 1333 +++++++++++++++++-------------- neo/swf/SWF_Load.cpp | 7 +- neo/swf/SWF_Main.cpp | 126 +-- neo/swf/SWF_PlaceObject.cpp | 25 +- neo/swf/SWF_ScriptFunction.cpp | 22 +- neo/swf/SWF_ScriptFunction.h | 46 +- neo/swf/SWF_ScriptObject.cpp | 36 +- neo/swf/SWF_ScriptObject.h | 15 +- neo/swf/SWF_ScriptVar.h | 49 +- neo/swf/SWF_ShapeParser.cpp | 135 ++-- neo/swf/SWF_ShapeParser.h | 10 +- neo/swf/SWF_SpriteInstance.cpp | 192 +++-- neo/swf/SWF_SpriteInstance.h | 2 +- neo/swf/SWF_TextInstance.cpp | 2 +- neo/swf/SWF_TextInstance.h | 15 +- neo/swf/SWF_Types.h | 2 +- 25 files changed, 1818 insertions(+), 1452 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index 00d171e84f..d28a082d58 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -315,7 +315,8 @@ class idSWF SWF_NATIVE_VAR_DECLARE_NESTED( crop, idSWF ); class idSWFScriptFunction_Object; - SWF_NATIVE_VAR_DECLARE_NESTED_READONLY( Object, idSWFScriptFunction_Object, Call( object, idSWFParmList() ) ); class idSWFScriptFunction_Object : public idSWFScriptFunction + SWF_NATIVE_VAR_DECLARE_NESTED_READONLY( Object, idSWFScriptFunction_Object, Call( object, idSWFParmList() ) ); + class idSWFScriptFunction_Object : public idSWFScriptFunction { public: idSWFScriptVar Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) @@ -527,8 +528,8 @@ class idSWF //---------------------------------- // SWF_Abc.cpp //---------------------------------- - void DoABC( idSWFBitStream & bitstream ) ; - void SymbolClass( idSWFBitStream & bitstream ) ; + void DoABC( idSWFBitStream& bitstream ) ; + void SymbolClass( idSWFBitStream& bitstream ) ; // RB begin bool Deflate( const byte* input, int inputSize, byte* output, int& outputSize ); @@ -545,7 +546,7 @@ class idSWF static const char* GetTagName( swfTag_t tag ); static const char* GetActionName( swfAction_t action ); - void CreateAbcObjects( idSWFScriptObject *globals ); + void CreateAbcObjects( idSWFScriptObject* globals ); SWF_SymbolClass symbolClasses; }; diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index 385aff23f7..5501ae23ca 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -16,7 +16,7 @@ Copyright (C) 2022 HvanGinneken // trace( text1.text ) // text1.text = "clicked me " + clickCount; //} -//// Register the function as a listener with the button. +//// Register the function as a listener with the button. //addEventListener( MouseEvent.CLICK, playAnimation ); #include "precompiled.h" @@ -24,12 +24,13 @@ Copyright (C) 2022 HvanGinneken #include "SWF_Abc.h" -idCVar swf_abc_verbose( "swf_abc_verbose", "1", CVAR_INTEGER, "1 : writes out all abc data read \n 2 : print bytecode "); +idCVar swf_abc_verbose( "swf_abc_verbose", "1", CVAR_INTEGER, "1 : writes out all abc data read \n 2 : print bytecode " ); #pragma warning( disable: 4189 ) // local variable is initialized but not referenced -void trace( const char *fmt, ... ) { - if ( swf_abc_verbose.GetInteger() == 1 ) +void trace( const char* fmt, ... ) +{ + if( swf_abc_verbose.GetInteger() == 1 ) { //common->PrintPrefix("[SWF]"); va_list argptr; @@ -42,485 +43,571 @@ void trace( const char *fmt, ... ) { #define toString(x) asString(x,constant_pool) -idStr SWF_AbcFile::asString( swfConstantKind_t kind, swfConstant_pool_info &constant_pool ) { +idStr SWF_AbcFile::asString( swfConstantKind_t kind, swfConstant_pool_info& constant_pool ) +{ idStr type; #define switchTrace( n ) case n: type = #n;break; - switch ( kind ) { - switchTrace( unused_0x00 ); - switchTrace( Utf8 ); - switchTrace( Int ); - switchTrace( UInt ); - switchTrace( PrivateNs ); - switchTrace( Double ); - switchTrace( Qname ); - switchTrace( Namespace ); - switchTrace( False ); - switchTrace( True ); - switchTrace( Null ); - switchTrace( QnameA ); - switchTrace( RTQname ); - switchTrace( RTQnameA ); - switchTrace( RTQnameL ); - switchTrace( RTQnameLA ); - switchTrace( Multiname ); - switchTrace( MultinameA ); - switchTrace( MultinameL ); - switchTrace( MultinameLA ); - switchTrace( PackageNamespace ); - switchTrace( PackageInternalNs ); - switchTrace( ProtectedNamespace ); - switchTrace( ExplicitNamespace ); - switchTrace( StaticProtectedNs ); + switch( kind ) + { + switchTrace( unused_0x00 ); + switchTrace( Utf8 ); + switchTrace( Int ); + switchTrace( UInt ); + switchTrace( PrivateNs ); + switchTrace( Double ); + switchTrace( Qname ); + switchTrace( Namespace ); + switchTrace( False ); + switchTrace( True ); + switchTrace( Null ); + switchTrace( QnameA ); + switchTrace( RTQname ); + switchTrace( RTQnameA ); + switchTrace( RTQnameL ); + switchTrace( RTQnameLA ); + switchTrace( Multiname ); + switchTrace( MultinameA ); + switchTrace( MultinameL ); + switchTrace( MultinameLA ); + switchTrace( PackageNamespace ); + switchTrace( PackageInternalNs ); + switchTrace( ProtectedNamespace ); + switchTrace( ExplicitNamespace ); + switchTrace( StaticProtectedNs ); } return type; #undef switchTrace } -idStr SWF_AbcFile::asString( swfMultiname *mn, swfConstant_pool_info &constant_pool,bool prefix /*= true*/ ) +idStr SWF_AbcFile::asString( swfMultiname* mn, swfConstant_pool_info& constant_pool, bool prefix /*= true*/ ) { idStr ret; - if (prefix) ret += toString( mn->type ); - switch ( mn->type ) { - case RTQnameL: - case RTQnameLA: - ret += "null::null"; - break; - case Qname: - case QnameA: - ret += " "; ret += *constant_pool.namespaceNames[mn->index]; - if (mn->index!=1) ret += "."; - ret += constant_pool.utf8Strings[mn->nameIndex]; - break; + if( prefix ) + { + ret += toString( mn->type ); + } + switch( mn->type ) + { + case RTQnameL: + case RTQnameLA: + ret += "null::null"; + break; + case Qname: + case QnameA: + ret += " "; + ret += *constant_pool.namespaceNames[mn->index]; + if( mn->index != 1 ) + { + ret += "."; + } + ret += constant_pool.utf8Strings[mn->nameIndex]; + break; - case RTQname: - case RTQnameA: - ret+= " ";ret+=constant_pool.utf8Strings[mn->nameIndex]; - break; + case RTQname: + case RTQnameA: + ret += " "; + ret += constant_pool.utf8Strings[mn->nameIndex]; + break; - case TypeName: - case Multiname: - case MultinameA: - ret += " "; ret += asString(&constant_pool.multinameInfos[mn->index],constant_pool); - ret += "."; ret += constant_pool.utf8Strings[mn->nameIndex]; - break; + case TypeName: + case Multiname: + case MultinameA: + ret += " "; + ret += asString( &constant_pool.multinameInfos[mn->index], constant_pool ); + ret += "."; + ret += constant_pool.utf8Strings[mn->nameIndex]; + break; - case MultinameL: - case MultinameLA: - ret += " "; for ( auto * str : constant_pool.namespaceSets[mn->index] ){ ret += *str; ret+="."; }; - break; - case unused_0x00: - ret += " unused_0x00"; - break; - default: - common->FatalError( "Invalid Multiname type" ); - break; + case MultinameL: + case MultinameLA: + ret += " "; + for( auto* str : constant_pool.namespaceSets[mn->index] ) + { + ret += *str; + ret += "."; + }; + break; + case unused_0x00: + ret += " unused_0x00"; + break; + default: + common->FatalError( "Invalid Multiname type" ); + break; } return ret; } -void SWF_AbcFile::traceMN( const char *name, swfMultiname *mn, swfConstant_pool_info &constant_pool ) +void SWF_AbcFile::traceMN( const char* name, swfMultiname* mn, swfConstant_pool_info& constant_pool ) { - idStr type = asString(mn,constant_pool ); - trace( "%s %s \n",name,type.c_str() ); + idStr type = asString( mn, constant_pool ); + trace( "%s %s \n", name, type.c_str() ); } -void SWF_AbcFile::traceConstantPool( swfConstant_pool_info &constant_pool ) +void SWF_AbcFile::traceConstantPool( swfConstant_pool_info& constant_pool ) { int cnt = 0; - - trace("^8========================================================\n" ); - trace(" constant pool \n" ); - trace("^8========================================================\n" ); - trace("^8integers : ^7%i\n", constant_pool.integers.Num() ); - for (auto& t : constant_pool.integers) + trace( "^8========================================================\n" ); + trace( " constant pool \n" ); + trace( "^8========================================================\n" ); + + trace( "^8integers : ^7%i\n", constant_pool.integers.Num() ); + for( auto& t : constant_pool.integers ) + { trace( "^8[^7%i^8]\t ^7%i \n", cnt++, t ); - trace( "^8uIntegers ^7: %i\n", constant_pool.uIntegers.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.uIntegers ) - trace( "^8[^7%i^8]\t ^7%i \n",cnt++, (int)t ); - trace( "^8doubles ^7: %i\n", constant_pool.doubles.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.doubles ) - trace( "^8[^7%i^8]\t ^7%f \n",cnt++, ( float ) t ); - trace( "^8utf8Strings ^7: %i\n", constant_pool.utf8Strings.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.utf8Strings ) - trace( "^8[^7%i^8]\t ^7%s \n",cnt++, t.c_str( ) ); - trace( "^8namespaceNames ^7: %i\n", constant_pool.namespaceNames.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.namespaceNames ) + } + trace( "^8uIntegers ^7: %i\n", constant_pool.uIntegers.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.uIntegers ) + { + trace( "^8[^7%i^8]\t ^7%i \n", cnt++, ( int )t ); + } + trace( "^8doubles ^7: %i\n", constant_pool.doubles.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.doubles ) + { + trace( "^8[^7%i^8]\t ^7%f \n", cnt++, ( float ) t ); + } + trace( "^8utf8Strings ^7: %i\n", constant_pool.utf8Strings.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.utf8Strings ) + { + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t.c_str( ) ); + } + trace( "^8namespaceNames ^7: %i\n", constant_pool.namespaceNames.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.namespaceNames ) + { trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t->c_str( ) ); + } - trace( "^8namespaceSets ^7: %i\n", constant_pool.namespaceSets.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.namespaceSets ) + trace( "^8namespaceSets ^7: %i\n", constant_pool.namespaceSets.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.namespaceSets ) { - for ( auto &ts : t ) + for( auto& ts : t ) + { trace( "^8[^7%i^8]\t ^7%s \n", cnt++, ts->c_str( ) ); + } } - - trace( "^8multinameInfos ^7: %i\n", constant_pool.multinameInfos.Num( ) ); cnt = 0; - for ( auto &t : constant_pool.multinameInfos ) + + trace( "^8multinameInfos ^7: %i\n", constant_pool.multinameInfos.Num( ) ); + cnt = 0; + for( auto& t : constant_pool.multinameInfos ) { - idStr pre="^8[^7";pre+=idStr(cnt++);pre+="^8]^7\t"; - traceMN(pre.c_str(),&t,constant_pool); + idStr pre = "^8[^7"; + pre += idStr( cnt++ ); + pre += "^8]^7\t"; + traceMN( pre.c_str(), &t, constant_pool ); } - trace("^8========================================================\n" ); + trace( "^8========================================================\n" ); } -void ReadMultiName( idSWFBitStream & bitstream ,swfMultiname & target ) +void ReadMultiName( idSWFBitStream& bitstream , swfMultiname& target ) { - target.type = (swfConstantKind_t )bitstream.ReadU8(); + target.type = ( swfConstantKind_t )bitstream.ReadU8(); target.index = 0; target.nameIndex = 0; - switch ( target.type ) + switch( target.type ) { - case RTQnameL: - case RTQnameLA: - //0,0 - break; - case Qname: - case QnameA: - target.index = bitstream.ReadEncodedU32(); - target.nameIndex = bitstream.ReadEncodedU32(); - break; + case RTQnameL: + case RTQnameLA: + //0,0 + break; + case Qname: + case QnameA: + target.index = bitstream.ReadEncodedU32(); + target.nameIndex = bitstream.ReadEncodedU32(); + break; - case RTQname: - case RTQnameA: - target.nameIndex = bitstream.ReadEncodedU32(); - break; + case RTQname: + case RTQnameA: + target.nameIndex = bitstream.ReadEncodedU32(); + break; - case TypeName: - target.nameIndex = bitstream.ReadEncodedU32( ); - target.nameIndexT =bitstream.ReadEncodedU32( ); - target.indexT = bitstream.ReadEncoded( ); - break; - case Multiname: - case MultinameA: - target.nameIndex = bitstream.ReadEncodedU32( ); - target.index = bitstream.ReadEncodedU32( ); - break; + case TypeName: + target.nameIndex = bitstream.ReadEncodedU32( ); + target.nameIndexT = bitstream.ReadEncodedU32( ); + target.indexT = bitstream.ReadEncoded( ); + break; + case Multiname: + case MultinameA: + target.nameIndex = bitstream.ReadEncodedU32( ); + target.index = bitstream.ReadEncodedU32( ); + break; - case MultinameL: - case MultinameLA: - target.index = bitstream.ReadEncodedU32( ); - break; - default: - common->FatalError("Invalid Multiname type"); - break; + case MultinameL: + case MultinameLA: + target.index = bitstream.ReadEncodedU32( ); + break; + default: + common->FatalError( "Invalid Multiname type" ); + break; } } -void ReadConstantPoolInfo( idSWFBitStream & bitstream , swfConstant_pool_info & target ) +void ReadConstantPoolInfo( idSWFBitStream& bitstream , swfConstant_pool_info& target ) { /*cpool_info{}*/ uint32 int_count = bitstream.ReadEncodedU32( ) ; target.integers.Alloc( ) = 0; - for ( uint i = 1; i < int_count; i++ ) + for( uint i = 1; i < int_count; i++ ) + { target.integers.Alloc( ) = bitstream.ReadEncoded( ); + } - uint32 uint_count = bitstream.ReadEncodedU32( ); + uint32 uint_count = bitstream.ReadEncodedU32( ); target.uIntegers.Alloc( ) = 0; - for ( uint i = 1; i < uint_count; i++ ) + for( uint i = 1; i < uint_count; i++ ) + { target.uIntegers.Alloc( ) = bitstream.ReadEncodedU32( ); + } uint32 double_count = bitstream.ReadEncodedU32( ); target.doubles.Alloc( ) = 0.0; - for ( uint i = 1; i < double_count; i++ ) + for( uint i = 1; i < double_count; i++ ) + { target.doubles.Alloc( ) = bitstream.ReadDouble( ); + } - uint32 string_count = bitstream.ReadEncodedU32( ); - target.utf8Strings.Alloc( ).Append("*"); - for ( uint i = 1; i < string_count; i++ ) { + uint32 string_count = bitstream.ReadEncodedU32( ); + target.utf8Strings.Alloc( ).Append( "*" ); + for( uint i = 1; i < string_count; i++ ) + { uint32 str_len = bitstream.ReadEncodedU32( ); - target.utf8Strings.Alloc( ).Append( ( char * ) bitstream.ReadData( str_len ),str_len ); + target.utf8Strings.Alloc( ).Append( ( char* ) bitstream.ReadData( str_len ), str_len ); } uint32 namespace_count = bitstream.ReadEncodedU32( ); target.namespaceNames.Alloc( ) = &target.utf8Strings[0]; - for ( uint i = 1; i < namespace_count; i++ ) { - target.namespaceKinds.Alloc() = (swfConstantKind_t)bitstream.ReadU8(); + for( uint i = 1; i < namespace_count; i++ ) + { + target.namespaceKinds.Alloc() = ( swfConstantKind_t )bitstream.ReadU8(); uint32 str_idx = bitstream.ReadEncodedU32( ); - target.namespaceNames.Alloc( ) = &target.utf8Strings[(int)str_idx]; + target.namespaceNames.Alloc( ) = &target.utf8Strings[( int )str_idx]; } uint32 namespace_set_count = bitstream.ReadEncodedU32( ); target.namespaceSets.Alloc( ).Alloc() = target.namespaceNames[0]; - for ( uint i = 1; i < namespace_set_count; i++ ) { + for( uint i = 1; i < namespace_set_count; i++ ) + { uint32 count = bitstream.ReadEncodedU32( ); - auto & newSet = target.namespaceSets.Alloc(); - for (uint j = 0; j < count; j++) + auto& newSet = target.namespaceSets.Alloc(); + for( uint j = 0; j < count; j++ ) { uint32 idx = bitstream.ReadEncodedU32( ); - newSet.Alloc() = target.namespaceNames[(int)idx]; + newSet.Alloc() = target.namespaceNames[( int )idx]; } } uint32 multiname_count = bitstream.ReadEncodedU32( ); - auto & empty = target.multinameInfos.Alloc( ); + auto& empty = target.multinameInfos.Alloc( ); empty.index = 0; empty.nameIndex = 0; - empty.type = unused_0x00; - for ( uint i = 1; i < multiname_count; i++ ) { - auto &newMn = target.multinameInfos.Alloc( ); - ReadMultiName(bitstream,newMn); + empty.type = unused_0x00; + for( uint i = 1; i < multiname_count; i++ ) + { + auto& newMn = target.multinameInfos.Alloc( ); + ReadMultiName( bitstream, newMn ); } } -void SWF_AbcFile::ReadOptionInfo( idSWFBitStream &bitstream, swfOption_info &newOption ) +void SWF_AbcFile::ReadOptionInfo( idSWFBitStream& bitstream, swfOption_info& newOption ) { newOption.option_count = bitstream.ReadEncodedU32( ); - for ( uint i = 0; i < newOption.option_count; i++ ) { - auto &newItem = newOption.options.Alloc( ); + for( uint i = 0; i < newOption.option_count; i++ ) + { + auto& newItem = newOption.options.Alloc( ); newItem.val = bitstream.ReadEncodedU32( ); newItem.kind = constant_pool.namespaceKinds[bitstream.ReadEncodedU32( )]; } } -void SWF_AbcFile::ReadMetaDataInfo ( idSWFBitStream & bitstream , swfMetadata_info & newMetadata ) +void SWF_AbcFile::ReadMetaDataInfo( idSWFBitStream& bitstream , swfMetadata_info& newMetadata ) { newMetadata.name = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; uint32 item_count = bitstream.ReadEncodedU32(); - for (uint i = 0; i < item_count; i++ ) { - auto & newItem = newMetadata.items.Alloc(); + for( uint i = 0; i < item_count; i++ ) + { + auto& newItem = newMetadata.items.Alloc(); newItem.key = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; newItem.value = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; } } -void SWF_AbcFile::ReadTraitData( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ) +void SWF_AbcFile::ReadTraitData( idSWFBitStream& bitstream, swfTraits_info& newTraitsData ) { - swfTraits_info::Type kind = (swfTraits_info::Type)((newTraitsData.kind << 4) >> 4); // snip upper half, lower 4 bits should remain. - uint8 attrib = (newTraitsData.kind >> 4); // snip lower half, upper 4 bits should remain. - - switch ( kind ) { - case swfTraits_info::Trait_Slot: - case swfTraits_info::Trait_Const: { - newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_slot ) ,TAG_SWF ); - swfTrait_slot &slot = *(( swfTrait_slot * )( newTraitsData.data )); - slot.slot_id = bitstream.ReadEncodedU32(); - slot.type_name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; - slot.vindex = bitstream.ReadEncodedU32(); - if ( slot.vindex != 0 ) - slot.vkind = bitstream.ReadU8(); - }break; - case swfTraits_info::Trait_Method: - case swfTraits_info::Trait_Getter: - case swfTraits_info::Trait_Setter:{ - newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_method ), TAG_SWF); - swfTrait_method &method = *( swfTrait_method * )( newTraitsData.data ); - method.disp_id = bitstream.ReadEncodedU32( ); - method.method = &methods[bitstream.ReadEncodedU32( )]; - }break; - case swfTraits_info::Trait_Class:{ - newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ), TAG_SWF); - swfTrait_class &tclass = *( swfTrait_class * )( newTraitsData.data ); - tclass.slot_id = bitstream.ReadEncodedU32( ); - tclass.classi = &classes[bitstream.ReadEncodedU32( )]; - }break; - case swfTraits_info::Trait_Function:{ - newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ), TAG_SWF); - swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); - func.slot_id = bitstream.ReadEncodedU32( ); - func.func = &methods[bitstream.ReadEncodedU32( )]; - }break; - - default: - common->FatalError("Unknown trait data"); + swfTraits_info::Type kind = ( swfTraits_info::Type )( ( newTraitsData.kind << 4 ) >> 4 ); // snip upper half, lower 4 bits should remain. + uint8 attrib = ( newTraitsData.kind >> 4 ); // snip lower half, upper 4 bits should remain. + + switch( kind ) + { + case swfTraits_info::Trait_Slot: + case swfTraits_info::Trait_Const: + { + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_slot ) , TAG_SWF ); + swfTrait_slot& slot = *( ( swfTrait_slot* )( newTraitsData.data ) ); + slot.slot_id = bitstream.ReadEncodedU32(); + slot.type_name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + slot.vindex = bitstream.ReadEncodedU32(); + if( slot.vindex != 0 ) + { + slot.vkind = bitstream.ReadU8(); + } + } + break; + case swfTraits_info::Trait_Method: + case swfTraits_info::Trait_Getter: + case swfTraits_info::Trait_Setter: + { + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_method ), TAG_SWF ); + swfTrait_method& method = *( swfTrait_method* )( newTraitsData.data ); + method.disp_id = bitstream.ReadEncodedU32( ); + method.method = &methods[bitstream.ReadEncodedU32( )]; + } + break; + case swfTraits_info::Trait_Class: + { + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ), TAG_SWF ); + swfTrait_class& tclass = *( swfTrait_class* )( newTraitsData.data ); + tclass.slot_id = bitstream.ReadEncodedU32( ); + tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + } break; + case swfTraits_info::Trait_Function: + { + newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ), TAG_SWF ); + swfTrait_function& func = *( swfTrait_function* )( newTraitsData.data ); + func.slot_id = bitstream.ReadEncodedU32( ); + func.func = &methods[bitstream.ReadEncodedU32( )]; + } + break; + + default: + common->FatalError( "Unknown trait data" ); + break; } } struct idSWFScriptObject::swfNamedVar_t ; template<> -idSWFScriptObject::swfNamedVar_t * SWF_AbcFile::GetTrait( const swfTraits_info &trait,idSWFScriptObject * globals ) { - swfTraits_info::Type kind = ( swfTraits_info::Type ) ( ( trait.kind << 4 ) >> 4 ); // snip upper half, lower 4 bits should remain. +idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& trait, idSWFScriptObject* globals ) +{ + swfTraits_info::Type kind = ( swfTraits_info::Type )( ( trait.kind << 4 ) >> 4 ); // snip upper half, lower 4 bits should remain. uint8 attrib = ( trait.kind >> 4 ); // snip lower half, upper 4 bits should remain. //idSWFScriptObject* newObj = new idSWFScriptObject(); - idSWFScriptObject::swfNamedVar_t * newVar = new idSWFScriptObject::swfNamedVar_t(); + idSWFScriptObject::swfNamedVar_t* newVar = new idSWFScriptObject::swfNamedVar_t(); newVar->value.traitsInfo = &trait; - switch ( kind ) { - case swfTraits_info::Trait_Slot: - case swfTraits_info::Trait_Const: - { //member variable. - swfTrait_slot &slot = *( ( swfTrait_slot * ) ( trait.data ) ); - newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; - //if ( slot.slot_id ) - //{ - // newVar = newObj->GetVariable(slot.slot_id,true); - // newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; - //}else - // newVar = newObj->GetVariable(constant_pool.utf8Strings[trait.name->nameIndex].c_str(),true); - - if ( slot.vindex != 0 ) - switch ( slot.vkind ) { - case Utf8: - newVar->value.SetString(constant_pool.utf8Strings[slot.vindex]); - break; - case Int: - newVar->value.SetInteger(constant_pool.integers[slot.vindex]); - break; - case UInt: - newVar->value.SetInteger((int32)(constant_pool.uIntegers[slot.vindex])); - break; - case Double: // crap. - newVar->value.SetFloat((float)(constant_pool.doubles[slot.vindex])); - break; - case Qname: - { - - } - case Namespace: - newVar->value.SetString(*constant_pool.namespaceNames[slot.vindex]); - break; - case Multiname: - break; - case False: - newVar->value.SetBool(false); - break; - case True: - newVar->value.SetBool(true); - break; - case Null: - newVar->value.SetUndefined(); - break; - case QnameA: + switch( kind ) + { + case swfTraits_info::Trait_Slot: + case swfTraits_info::Trait_Const: { - idStr &typeName = constant_pool.utf8Strings[slot.vindex]; - if ( globals->HasProperty( typeName.c_str( ) ) ) - newVar->value.SetObject( globals->GetObject( typeName ) ); + //member variable. + swfTrait_slot& slot = *( ( swfTrait_slot* )( trait.data ) ); + newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + //if ( slot.slot_id ) + //{ + // newVar = newObj->GetVariable(slot.slot_id,true); + // newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + //}else + // newVar = newObj->GetVariable(constant_pool.utf8Strings[trait.name->nameIndex].c_str(),true); + + if( slot.vindex != 0 ) + switch( slot.vkind ) + { + case Utf8: + newVar->value.SetString( constant_pool.utf8Strings[slot.vindex] ); + break; + case Int: + newVar->value.SetInteger( constant_pool.integers[slot.vindex] ); + break; + case UInt: + newVar->value.SetInteger( ( int32 )( constant_pool.uIntegers[slot.vindex] ) ); + break; + case Double: // crap. + newVar->value.SetFloat( ( float )( constant_pool.doubles[slot.vindex] ) ); + break; + case Qname: + { + + } + case Namespace: + newVar->value.SetString( *constant_pool.namespaceNames[slot.vindex] ); + break; + case Multiname: + break; + case False: + newVar->value.SetBool( false ); + break; + case True: + newVar->value.SetBool( true ); + break; + case Null: + newVar->value.SetUndefined(); + break; + case QnameA: + { + idStr& typeName = constant_pool.utf8Strings[slot.vindex]; + if( globals->HasProperty( typeName.c_str( ) ) ) + { + newVar->value.SetObject( globals->GetObject( typeName ) ); + } + else + { + newVar->value.SetUndefined(); + } + break; + } + break; + case MultinameA: + break; + case RTQname: + break; + case RTQnameA: + break; + case RTQnameL: + break; + case RTQnameLA: + break; + case NamespaceSet: + break; + case PackageNamespace: + break; + case PackageInternalNs: + break; + case ProtectedNamespace: + break; + case ExplicitNamespace: + break; + case StaticProtectedNs: + break; + case MultinameL: + break; + case MultinameLA: + break; + case TypeName: + break; + default: + break; + } else - newVar->value.SetUndefined(); - break; - } - break; - case MultinameA: - break; - case RTQname: - break; - case RTQnameA: - break; - case RTQnameL: - break; - case RTQnameLA: - break; - case NamespaceSet: - break; - case PackageNamespace: - break; - case PackageInternalNs: - break; - case ProtectedNamespace: - break; - case ExplicitNamespace: - break; - case StaticProtectedNs: - break; - case MultinameL: - break; - case MultinameLA: - break; - case TypeName: - break; - default: - break; + { + idStr& typeName = constant_pool.utf8Strings[slot.type_name->nameIndex]; + if( globals->HasProperty( typeName.c_str( ) ) ) + { + auto* newobj = idSWFScriptObject::Alloc(); + newobj->SetPrototype( globals->GetObject( typeName.c_str() ) ); + newVar->value.SetObject( newobj ); + } + else + { + newVar->value.SetUndefined(); + } + break; + } + + return newVar; } - else + break; + case swfTraits_info::Trait_Method: + case swfTraits_info::Trait_Getter: + case swfTraits_info::Trait_Setter: { - idStr &typeName = constant_pool.utf8Strings[slot.type_name->nameIndex]; - if ( globals->HasProperty( typeName.c_str( ) ) ) + newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; + swfTrait_method& method = *( ( swfTrait_method* )( trait.data ) ); + + idStrPtr name = method.method->name; + idStr owner; + //string method owner + //common->FatalError("This is wrong. now dont keep using the debug info but start resolving it properly!!!!"); + //check frame scripts! + int slashPos = name->Find( "/" ); + if( slashPos != -1 ) + { + owner = idStr( name->c_str(), 0, slashPos ); + } + + slashPos = owner.Find( ":" ); + if( slashPos != -1 ) { - auto * newobj = idSWFScriptObject::Alloc(); - newobj->SetPrototype( globals->GetObject( typeName.c_str() )); - newVar->value.SetObject( newobj ); + owner = idStr( owner.c_str( ), slashPos + 1, owner.Length() ); + } + + if( globals->HasProperty( owner.c_str() ) ) + { + idSWFScriptFunction_Script* func = idSWFScriptFunction_Script::Alloc( ); + func->SetAbcFile( this ); + func->SetData( method.method ); + newVar->value = idSWFScriptVar( func ) ; } else - newVar->value.SetUndefined(); + { + newVar->value.SetUndefined( ); + } break; - } - return newVar; - }break; - case swfTraits_info::Trait_Method: - case swfTraits_info::Trait_Getter: - case swfTraits_info::Trait_Setter: - { - newVar->name = constant_pool.utf8Strings[trait.name->nameIndex]; - swfTrait_method &method = *( ( swfTrait_method * ) ( trait.data ) ); - - idStrPtr name = method.method->name; - idStr owner; - //string method owner - //common->FatalError("This is wrong. now dont keep using the debug info but start resolving it properly!!!!"); - //check frame scripts! - int slashPos = name->Find("/"); - if (slashPos != -1) - owner = idStr(name->c_str(),0,slashPos); - - slashPos = owner.Find( ":" ); - if ( slashPos != -1 ) - owner = idStr( owner.c_str( ), slashPos+1, owner.Length() ); - - if ( globals->HasProperty( owner.c_str() ) ) { - idSWFScriptFunction_Script *func = idSWFScriptFunction_Script::Alloc( ); - func->SetAbcFile( this ); - func->SetData( method.method ); - newVar->value= idSWFScriptVar( func ) ; - } else - newVar->value.SetUndefined( ); + } + break; + case swfTraits_info::Trait_Class: + { + int a = 0; + //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ) ); + //swfTrait_class &tclass = *( swfTrait_class * ) ( newTraitsData.data ); + //tclass.slot_id = bitstream.ReadEncodedU32( ); + //tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + } break; - - }break; - case swfTraits_info::Trait_Class: - { - int a = 0; - //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ) ); - //swfTrait_class &tclass = *( swfTrait_class * ) ( newTraitsData.data ); - //tclass.slot_id = bitstream.ReadEncodedU32( ); - //tclass.classi = &classes[bitstream.ReadEncodedU32( )]; - }break; - case swfTraits_info::Trait_Function: - { - int a = 0; - //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ) ); - //swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); - //func.slot_id = bitstream.ReadEncodedU32( ); - //func.func = &methods[bitstream.ReadEncodedU32( )]; - }break; - - default: - common->FatalError( "Unknown trait data" ); + case swfTraits_info::Trait_Function: + { + int a = 0; + //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ) ); + //swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); + //func.slot_id = bitstream.ReadEncodedU32( ); + //func.func = &methods[bitstream.ReadEncodedU32( )]; + } break; + + default: + common->FatalError( "Unknown trait data" ); + break; } return newVar; } -void SWF_AbcFile::ReadTraitsInfo( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ) +void SWF_AbcFile::ReadTraitsInfo( idSWFBitStream& bitstream, swfTraits_info& newTraitsData ) { newTraitsData.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; - //The kind field contains two four-bit fields. The lower four bits determine the kind of this trait. The - // upper four bits comprise a bit vector providing attributes of the trait. See the following tables and - // sections for full descriptions. + //The kind field contains two four-bit fields. The lower four bits determine the kind of this trait. The + // upper four bits comprise a bit vector providing attributes of the trait. See the following tables and + // sections for full descriptions. newTraitsData.kind = bitstream.ReadU8(); ReadTraitData( bitstream, newTraitsData ); uint8 attrib = ( newTraitsData.kind >> 4 ); // snip lower half, upper 4 bits should remain. - if ((attrib & swfTraits_info::Attrib::Metadata) != 0 ) { - uint32 meta_count = bitstream.ReadEncodedU32(); - for (uint i = 0 ; i < meta_count; i++) { + if( ( attrib & swfTraits_info::Attrib::Metadata ) != 0 ) + { + uint32 meta_count = bitstream.ReadEncodedU32(); + for( uint i = 0 ; i < meta_count; i++ ) + { newTraitsData.metadatas.Alloc() = &metadatas[bitstream.ReadEncodedU32()]; - //fix this. + //fix this. } } } -void SWF_AbcFile::ReadClassInfo( idSWFBitStream &bitstream, swfClass_info &newClassData ) +void SWF_AbcFile::ReadClassInfo( idSWFBitStream& bitstream, swfClass_info& newClassData ) { newClassData.cinit = &methods[bitstream.ReadEncodedU32()]; uint32 trait_count = bitstream.ReadEncodedU32(); - newClassData.traits.AssureSize(trait_count); - for ( uint i = 0; i < trait_count; i++ ) { + newClassData.traits.AssureSize( trait_count ); + for( uint i = 0; i < trait_count; i++ ) + { ReadTraitsInfo( bitstream, newClassData.traits[i] ); } @@ -528,22 +615,23 @@ void SWF_AbcFile::ReadClassInfo( idSWFBitStream &bitstream, swfClass_info &newCl //The last entry in that array is the entry point for the ABC file; that is, the last entry�s //initialization method contains the first bytecode that�s run when the ABC file is executed. -void SWF_AbcFile::ReadScriptInfo( idSWFBitStream &bitstream, swfScript_info &newScriptData ) +void SWF_AbcFile::ReadScriptInfo( idSWFBitStream& bitstream, swfScript_info& newScriptData ) { uint32 init = bitstream.ReadEncodedU32( ); uint32 trait_count = bitstream.ReadEncodedU32( ); newScriptData.init = &methods[init]; - trace("%s \n",newScriptData.init->name->c_str()); - newScriptData.traits.AssureSize(trait_count); - for ( uint i = 0; i < trait_count; i++ ) { + trace( "%s \n", newScriptData.init->name->c_str() ); + newScriptData.traits.AssureSize( trait_count ); + for( uint i = 0; i < trait_count; i++ ) + { ReadTraitsInfo( bitstream, newScriptData.traits[i] ); } } -void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream &bitstream, swfMethod_body_info &newMethodBody ) +void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream& bitstream, swfMethod_body_info& newMethodBody ) { newMethodBody.method = &methods[bitstream.ReadEncodedU32()]; - assert(newMethodBody.method->body==nullptr); + assert( newMethodBody.method->body == nullptr ); newMethodBody.method->body = &newMethodBody; newMethodBody.max_stack = bitstream.ReadEncodedU32(); @@ -551,29 +639,31 @@ void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream &bitstream, swfMethod_body_ newMethodBody.initScopeDepth = bitstream.ReadEncodedU32(); newMethodBody.maxScopeDepth = bitstream.ReadEncodedU32(); newMethodBody.codeLength = bitstream.ReadEncodedU32(); - newMethodBody.code.Load(bitstream.ReadData(newMethodBody.codeLength),newMethodBody.codeLength,true);// ( byte * ) Mem_ClearedAlloc( sizeof( byte ) * newMethodBody.codeLength ); - extern void swf_PrintStream(SWF_AbcFile * file ,idSWFBitStream & bitstream); - if ( swf_abc_verbose.GetInteger( ) == 2 ) + newMethodBody.code.Load( bitstream.ReadData( newMethodBody.codeLength ), newMethodBody.codeLength, true ); // ( byte * ) Mem_ClearedAlloc( sizeof( byte ) * newMethodBody.codeLength ); + extern void swf_PrintStream( SWF_AbcFile * file , idSWFBitStream & bitstream ); + if( swf_abc_verbose.GetInteger( ) == 2 ) { - common->Printf("============================\n"); - common->Printf("Method %s 's bytecode \n",newMethodBody.method->name->c_str()); - common->Printf("============================\n"); - swf_PrintStream(this,newMethodBody.code); + common->Printf( "============================\n" ); + common->Printf( "Method %s 's bytecode \n", newMethodBody.method->name->c_str() ); + common->Printf( "============================\n" ); + swf_PrintStream( this, newMethodBody.code ); } //memcpy(newMethodBody.code,bitstream.ReadData(newMethodBody.codeLength),newMethodBody.codeLength); uint32 exception_count = bitstream.ReadEncodedU32( ); - for ( uint i = 0; i < exception_count; i++ ) { - auto &newExceptionInfo = newMethodBody.exceptions.Alloc( ); + for( uint i = 0; i < exception_count; i++ ) + { + auto& newExceptionInfo = newMethodBody.exceptions.Alloc( ); ReadExceptionInfo( bitstream, newExceptionInfo ); } uint32 trait_count = bitstream.ReadEncodedU32( ); - for ( uint i = 0; i < trait_count; i++ ) { - auto &newTrait = newMethodBody.traits.Alloc( ); + for( uint i = 0; i < trait_count; i++ ) + { + auto& newTrait = newMethodBody.traits.Alloc( ); ReadTraitsInfo( bitstream, newTrait ); } } -void SWF_AbcFile::ReadExceptionInfo( idSWFBitStream &bitstream, swfException_info &newException ) +void SWF_AbcFile::ReadExceptionInfo( idSWFBitStream& bitstream, swfException_info& newException ) { newException.from = bitstream.ReadEncodedU32( ); newException.to = bitstream.ReadEncodedU32(); @@ -582,44 +672,50 @@ void SWF_AbcFile::ReadExceptionInfo( idSWFBitStream &bitstream, swfException_inf newException.var_name = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; } -void SWF_AbcFile::ReadInstanceInfo( idSWFBitStream &bitstream, swfInstance_info &newInstancedata ) +void SWF_AbcFile::ReadInstanceInfo( idSWFBitStream& bitstream, swfInstance_info& newInstancedata ) { newInstancedata.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; newInstancedata.super_name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; - - if (swf_abc_verbose.GetBool()) + + if( swf_abc_verbose.GetBool() ) { traceMN( "newInstancedata.name", newInstancedata.name, constant_pool ); traceMN( "newInstancedata.super_name", newInstancedata.super_name, constant_pool ); } - newInstancedata.flags = (swfInstanceFlags_t)bitstream.ReadU8(); - if ( (newInstancedata.flags & swfInstanceFlags_t::ClassProtectedNs) != 0 ) + newInstancedata.flags = ( swfInstanceFlags_t )bitstream.ReadU8(); + if( ( newInstancedata.flags & swfInstanceFlags_t::ClassProtectedNs ) != 0 ) + { newInstancedata.protectedNs = bitstream.ReadEncodedU32(); + } uint32 interface_count = bitstream.ReadEncodedU32(); - for (uint i =0; i < interface_count; i++ ) + for( uint i = 0; i < interface_count; i++ ) + { newInstancedata.interfaces.Alloc() = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + } newInstancedata.iinit = &methods[bitstream.ReadEncodedU32()]; uint32 trait_count = bitstream.ReadEncodedU32( ); - for (uint i = 0; i < trait_count; i++ ) { - auto & newTrait = newInstancedata.traits.Alloc(); - ReadTraitsInfo(bitstream,newTrait); + for( uint i = 0; i < trait_count; i++ ) + { + auto& newTrait = newInstancedata.traits.Alloc(); + ReadTraitsInfo( bitstream, newTrait ); } } -void SWF_AbcFile::ReadMethodInfo ( idSWFBitStream & bitstream , swfMethod_info & newMethod ) +void SWF_AbcFile::ReadMethodInfo( idSWFBitStream& bitstream , swfMethod_info& newMethod ) { uint32 idx = 0; newMethod.paramCount = bitstream.ReadEncodedU32(); idx = bitstream.ReadEncodedU32(); newMethod.returnType = &constant_pool.multinameInfos[idx]; - for (uint i = 0; i < newMethod.paramCount; i++ ) { + for( uint i = 0; i < newMethod.paramCount; i++ ) + { idx = bitstream.ReadEncodedU32(); newMethod.paramTypes.Alloc() = &constant_pool.multinameInfos[idx]; } @@ -627,16 +723,19 @@ void SWF_AbcFile::ReadMethodInfo ( idSWFBitStream & bitstream , swfMethod_info & newMethod.name = &constant_pool.utf8Strings[idx]; newMethod.flags = bitstream.ReadU8(); newMethod.options.option_count = 0; - if ( (newMethod.flags & swfMethod_info::HAS_OPTIONAL) != 0 ) - ReadOptionInfo(bitstream,newMethod.options); + if( ( newMethod.flags & swfMethod_info::HAS_OPTIONAL ) != 0 ) + { + ReadOptionInfo( bitstream, newMethod.options ); + } trace( "newMethod.name %s \n", newMethod.name->c_str() ); - if ( (newMethod.flags & swfMethod_info::HAS_PARAM_NAMES) != 0 ) + if( ( newMethod.flags & swfMethod_info::HAS_PARAM_NAMES ) != 0 ) { - trace( "newMethod.params %i \n", (int)newMethod.paramCount); + trace( "newMethod.params %i \n", ( int )newMethod.paramCount ); - for ( uint i = 0; i < newMethod.paramCount; i++ ) { + for( uint i = 0; i < newMethod.paramCount; i++ ) + { idx = bitstream.ReadEncodedU32( ); newMethod.paramNames.Alloc() = &constant_pool.utf8Strings[idx]; @@ -646,76 +745,84 @@ void SWF_AbcFile::ReadMethodInfo ( idSWFBitStream & bitstream , swfMethod_info & } -//Remove Accessibility +//Remove Accessibility -void idSWF::DoABC( idSWFBitStream & bitstream ) { +void idSWF::DoABC( idSWFBitStream& bitstream ) +{ - SWF_AbcFile &newAbcFile = abcFile; - int strmSize = bitstream.Length( ) + 6; // codeLength(uin16) + recordLength(uin32) + SWF_AbcFile& newAbcFile = abcFile; + int strmSize = bitstream.Length( ) + 6; // codeLength(uin16) + recordLength(uin32) uint32 flags = bitstream.ReadU32(); - idStr name = bitstream.ReadString(); + idStr name = bitstream.ReadString(); int dataSize = bitstream.Length( ) - name.Length( ); common->Printf( "DoABC %s flags %i tagsize %i bytecode size %i \n", name.c_str( ), flags, strmSize, dataSize ); - + bitstream.ReadLittle( newAbcFile.minor_version ); bitstream.ReadLittle( newAbcFile.major_version ); - + ReadConstantPoolInfo( bitstream, newAbcFile.constant_pool ); - SWF_AbcFile::traceConstantPool(newAbcFile.constant_pool); + SWF_AbcFile::traceConstantPool( newAbcFile.constant_pool ); uint32 method_count = bitstream.ReadEncodedU32( ) ; - newAbcFile.methods.AssureSize(method_count); - trace("method_count %i \n", method_count ); - for ( uint i = 0; i < method_count; i++ ) { - auto &newMethod = newAbcFile.methods[i]; + newAbcFile.methods.AssureSize( method_count ); + trace( "method_count %i \n", method_count ); + for( uint i = 0; i < method_count; i++ ) + { + auto& newMethod = newAbcFile.methods[i]; newAbcFile.ReadMethodInfo( bitstream, newMethod ); } uint32 meta_count = bitstream.ReadEncodedU32( ); - newAbcFile.metadatas.AssureSize(meta_count); + newAbcFile.metadatas.AssureSize( meta_count ); trace( "meta_count %i \n", meta_count ); - for ( uint i = 0; i < meta_count; i++ ) { - auto &newMeta = newAbcFile.metadatas[i]; + for( uint i = 0; i < meta_count; i++ ) + { + auto& newMeta = newAbcFile.metadatas[i]; newAbcFile.ReadMetaDataInfo( bitstream, newMeta ); } newAbcFile.class_count = bitstream.ReadEncodedU32(); - newAbcFile.instances.AssureSize(newAbcFile.class_count); + newAbcFile.instances.AssureSize( newAbcFile.class_count ); trace( "class_count %i (Instance) \n", newAbcFile.class_count ); - for ( uint i = 0; i < newAbcFile.class_count ; i++ ) { - auto &newInstance = newAbcFile.instances[i]; + for( uint i = 0; i < newAbcFile.class_count ; i++ ) + { + auto& newInstance = newAbcFile.instances[i]; newAbcFile.ReadInstanceInfo( bitstream, newInstance ); } trace( "class_count %i (Class) \n", newAbcFile.class_count ); - newAbcFile.classes.AssureSize(newAbcFile.class_count); - for ( uint i = 0; i < newAbcFile.class_count ; i++ ) { - auto &newClass = newAbcFile.classes[i]; + newAbcFile.classes.AssureSize( newAbcFile.class_count ); + for( uint i = 0; i < newAbcFile.class_count ; i++ ) + { + auto& newClass = newAbcFile.classes[i]; newAbcFile.ReadClassInfo( bitstream, newClass ); } uint32 script_count = bitstream.ReadEncodedU32( ); newAbcFile.scripts.AssureSize( script_count ); trace( "script_count %i \n", script_count ); - for ( uint i = 0; i < script_count; i++ ) { - auto &newScript = newAbcFile.scripts[i]; + for( uint i = 0; i < script_count; i++ ) + { + auto& newScript = newAbcFile.scripts[i]; newAbcFile.ReadScriptInfo( bitstream, newScript ); } uint32 methBody_count = bitstream.ReadEncodedU32( ); - newAbcFile.method_bodies.AssureSize(methBody_count); + newAbcFile.method_bodies.AssureSize( methBody_count ); trace( "methBody_count %i \n", methBody_count ); - for ( uint i = 0; i < methBody_count; i++ ) { + for( uint i = 0; i < methBody_count; i++ ) + { - auto &newMethBody = newAbcFile.method_bodies[i]; + auto& newMethBody = newAbcFile.method_bodies[i]; newAbcFile.ReadMethodBodyInfo( bitstream, newMethBody ); } //Create trait objects - //resolve subclass/superclass relations. + //resolve subclass/superclass relations. } -void idSWF::SymbolClass( idSWFBitStream &bitstream ) { +void idSWF::SymbolClass( idSWFBitStream& bitstream ) +{ //Header RECORDHEADER Tag type = 76 //NumSymbols UI16 Number of symbols that will be associated by this tag. @@ -725,12 +832,12 @@ void idSWF::SymbolClass( idSWFBitStream &bitstream ) { //TagN U16 Tag ID for symbol N //NameN STRING Fully - qualified class name for symbol N uint16 numSymbols = bitstream.ReadU16(); - for (uint i = 0 ; i < numSymbols; i++ ) + for( uint i = 0 ; i < numSymbols; i++ ) { - auto & newSymbol = symbolClasses.symbols.Alloc(); + auto& newSymbol = symbolClasses.symbols.Alloc(); newSymbol.tag = bitstream.ReadU16( ); newSymbol.name = bitstream.ReadString( ); - common->Printf("SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i,newSymbol.tag,newSymbol.name.c_str()); + common->Printf( "SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i, newSymbol.tag, newSymbol.name.c_str() ); } //load bytecode diff --git a/neo/swf/SWF_Abc.h b/neo/swf/SWF_Abc.h index 344c109b55..82cf90a33a 100644 --- a/neo/swf/SWF_Abc.h +++ b/neo/swf/SWF_Abc.h @@ -25,7 +25,8 @@ struct swfConstant_pool_info struct swfMetadata_info { - struct item { //item_info + struct item //item_info + { idStrPtr key; //u30 key idStrPtr value; //u30 value }; @@ -35,7 +36,8 @@ struct swfMetadata_info struct swfOption_info { - struct item { //option_detail + struct item //option_detail + { uint32 val; //u30 val swfConstantKind_t kind; //u8 kind }; @@ -47,7 +49,8 @@ struct swfMethod_body_info; struct swfMethod_info { //zero before use. - enum Flags { + enum Flags + { NEED_ARGUMENTS = 0x01, // Suggests to the run - time that an �arguments� object( as specified by the ActionScript 3.0 Language Reference ) be created.Must not be used together with NEED_REST.See Chapter 3. NEED_ACTIVATION = 0x02, // Must be set if this method uses the newactivation opcode. NEED_REST = 0x04, // This flag creates an ActionScript 3.0 rest arguments array.Must not be used with NEED_ARGUMENTS.See Chapter 3. @@ -66,17 +69,19 @@ struct swfMethod_info swfOption_info options; //option_info options idStrPtrList paramNames; // ( param_info ) param_names u30 param_name[param_count] - swfMethod_body_info * body = nullptr; + swfMethod_body_info* body = nullptr; }; struct swfTraits_info { - enum Attrib { // upper 4 bits of kind + enum Attrib // upper 4 bits of kind + { Final = 0x1, // Is used with Trait_Method, Trait_Getter andTrait_Setter.It marks a method that cannot be overridden by a sub - class Override = 0x2, // Is used with Trait_Method, Trait_Getter andTrait_Setter.It marks a method that has been overridden in this class Metadata = 0x4, // Is used to signal that the fields metadata_count and metadata follow the data field in the traits_info entry }; - enum Type { + enum Type + { Trait_Slot = 0, Trait_Method = 1, Trait_Getter = 2, @@ -124,14 +129,16 @@ struct swfTrait_class swfClass_info* classi; //u30 classi }; -struct swfTrait_function { +struct swfTrait_function +{ uint32 slot_id; //u30 slot_id - swfMethod_info * func; //u30 function + swfMethod_info* func; //u30 function }; -struct swfTrait_method { +struct swfTrait_method +{ uint32 disp_id; //u30 disp_id - swfMethod_info * method; //u30 method + swfMethod_info* method; //u30 method }; struct swfScript_info @@ -151,7 +158,7 @@ struct swfException_info struct swfMethod_body_info { - swfMethod_info * method; //u30 method + swfMethod_info* method; //u30 method uint32 max_stack; //u30 max_stack uint32 localCount; //u30 local_count uint32 initScopeDepth; //u30 init_scope_depth @@ -166,30 +173,30 @@ class idSWFScriptObject; struct SWF_AbcFile { template - T *GetTrait( const swfTraits_info &trait, idSWFScriptObject * globals = nullptr ); - - void ReadMethodInfo ( idSWFBitStream &bitstream, swfMethod_info &newMethod ); - void ReadOptionInfo ( idSWFBitStream &bitstream, swfOption_info &newOption ); - void ReadMetaDataInfo ( idSWFBitStream &bitstream, swfMetadata_info &newMetadata ); - void ReadInstanceInfo ( idSWFBitStream &bitstream, swfInstance_info &newInstancedata ); - void ReadTraitData ( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ); - void ReadTraitsInfo ( idSWFBitStream &bitstream, swfTraits_info &newTraitsData ); - void ReadClassInfo ( idSWFBitStream &bitstream, swfClass_info &newClassData ); - void ReadScriptInfo ( idSWFBitStream &bitstream, swfScript_info &newScriptData ); - void ReadMethodBodyInfo ( idSWFBitStream &bitstream, swfMethod_body_info &newMethodBody ); - void ReadExceptionInfo ( idSWFBitStream &bitstream, swfException_info &newException ); - - static idStr asString( swfConstantKind_t kind, swfConstant_pool_info &constant_pool ); - static idStr asString( swfMultiname *mn, swfConstant_pool_info &constant_pool, bool prefix = true ); - static void traceMN( const char *name, swfMultiname *mn, swfConstant_pool_info &constant_pool ); - static void traceConstantPool( swfConstant_pool_info &constant_pool ); + T* GetTrait( const swfTraits_info& trait, idSWFScriptObject* globals = nullptr ); + + void ReadMethodInfo( idSWFBitStream& bitstream, swfMethod_info& newMethod ); + void ReadOptionInfo( idSWFBitStream& bitstream, swfOption_info& newOption ); + void ReadMetaDataInfo( idSWFBitStream& bitstream, swfMetadata_info& newMetadata ); + void ReadInstanceInfo( idSWFBitStream& bitstream, swfInstance_info& newInstancedata ); + void ReadTraitData( idSWFBitStream& bitstream, swfTraits_info& newTraitsData ); + void ReadTraitsInfo( idSWFBitStream& bitstream, swfTraits_info& newTraitsData ); + void ReadClassInfo( idSWFBitStream& bitstream, swfClass_info& newClassData ); + void ReadScriptInfo( idSWFBitStream& bitstream, swfScript_info& newScriptData ); + void ReadMethodBodyInfo( idSWFBitStream& bitstream, swfMethod_body_info& newMethodBody ); + void ReadExceptionInfo( idSWFBitStream& bitstream, swfException_info& newException ); + + static idStr asString( swfConstantKind_t kind, swfConstant_pool_info& constant_pool ); + static idStr asString( swfMultiname* mn, swfConstant_pool_info& constant_pool, bool prefix = true ); + static void traceMN( const char* name, swfMultiname* mn, swfConstant_pool_info& constant_pool ); + static void traceConstantPool( swfConstant_pool_info& constant_pool ); uint16 minor_version; uint16 major_version; swfConstant_pool_info constant_pool; idList methods; //u30 method_count method_info method[method_count] idList metadatas; //u30 metadata_count metadata_info metadata[metadata_count] - uint32 class_count; //u30 class_count + uint32 class_count; //u30 class_count idList instances; //instance_info instance[class_count] idList classes; //class_info class[class_count] idList scripts; //u30 script_count script_info script[script_count] @@ -206,7 +213,8 @@ struct SWF_SymbolClass idList symbols; }; -enum SWFAbcOpcode { +enum SWFAbcOpcode +{ #define ABC_OP(operandCount, canThrow, stack, internalOnly, nameToken) OP_##nameToken, #define ABC_UNUSED_OP(operandCount, canThrow, stack, internalOnly, nameToken) ABC_OP(operandCount, canThrow, stack, internalOnly, nameToken) #include "opcodes.tbl" @@ -217,12 +225,13 @@ enum SWFAbcOpcode { OP_end_of_op_codes }; -struct AbcOpcodeInfo { +struct AbcOpcodeInfo +{ int8_t operandCount; // uses -1 for "invalid", we can avoid that if necessary int8_t canThrow; // always 0 or 1 int8_t stack; // stack movement not taking into account run-time names or function arguments uint16_t wordCode; // a map used during translation - const char *name; // instruction name or OP_0xNN for undefined instructions #IFDEF DEBUGGER + const char* name; // instruction name or OP_0xNN for undefined instructions #IFDEF DEBUGGER }; extern const AbcOpcodeInfo opcodeInfo[]; diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index ea39e39efe..0f8174af34 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -87,12 +87,15 @@ class idSWFBitStream int32 ReadS32(); template< typename T > - T ReadEncoded(){ + T ReadEncoded() + { T result = 0; - for ( int i = 0; i < 5; i++ ) { + for( int i = 0; i < 5; i++ ) + { byte b = ReadU8( ); result |= ( b & 0x7F ) << ( 7 * i ); - if ( ( b & 0x80 ) == 0 ) { + if( ( b & 0x80 ) == 0 ) + { return result; } } diff --git a/neo/swf/SWF_Dictionary.cpp b/neo/swf/SWF_Dictionary.cpp index 5e334d3beb..724d1717e3 100644 --- a/neo/swf/SWF_Dictionary.cpp +++ b/neo/swf/SWF_Dictionary.cpp @@ -45,7 +45,7 @@ idSWFDictionaryEntry::idSWFDictionaryEntry() : imageAtlasOffset( 0, 0 ), channelScale( 1.0f, 1.0f, 1.0f, 1.0f ), scriptClass( ), - resolved ( false ), + resolved( false ), name( NULL ) { } diff --git a/neo/swf/SWF_Enums.h b/neo/swf/SWF_Enums.h index f5e115b39d..15d45db42d 100644 --- a/neo/swf/SWF_Enums.h +++ b/neo/swf/SWF_Enums.h @@ -74,7 +74,7 @@ enum swfConstantKind_t #endif }; -enum swfDictType_t +enum swfDictType_t { SWF_DICT_NULL, SWF_DICT_IMAGE, diff --git a/neo/swf/SWF_EventDispatcher.cpp b/neo/swf/SWF_EventDispatcher.cpp index 17aaa9567b..33f496f2f3 100644 --- a/neo/swf/SWF_EventDispatcher.cpp +++ b/neo/swf/SWF_EventDispatcher.cpp @@ -30,20 +30,21 @@ idSWFScriptObject_EventDispatcherPrototype idSWFScriptObject_EventDispatcherPrototype::idSWFScriptObject_EventDispatcherPrototype() { - SWF_EVENTDISPATCHER_NATIVE_VAR_SET ( MouseEvent ); - SWF_EVENTDISPATCHER_NATIVE_VAR_SET ( Event ); + SWF_EVENTDISPATCHER_NATIVE_VAR_SET( MouseEvent ); + SWF_EVENTDISPATCHER_NATIVE_VAR_SET( Event ); SWF_EVENTDISPATCHER_FUNCTION_SET( addEventListener ); } -SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( MouseEvent ){} -SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( Event ){} +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( MouseEvent ) {} +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_SET( Event ) {} -SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( MouseEvent ) { - static idSWFScriptObject * mouseEventObj = nullptr; - if (mouseEventObj == nullptr) +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( MouseEvent ) +{ + static idSWFScriptObject* mouseEventObj = nullptr; + if( mouseEventObj == nullptr ) { mouseEventObj = idSWFScriptObject::Alloc( ); - idSWFScriptObject *eventParms = idSWFScriptObject::Alloc( ); + idSWFScriptObject* eventParms = idSWFScriptObject::Alloc( ); eventParms->Set( "type", "MouseEvent" ); mouseEventObj->Set( "[MouseEvent]", eventParms ); @@ -70,15 +71,17 @@ SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( MouseEvent ) { return mouseEventObj; } -SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( Event ) { - static idSWFScriptObject *eventObj = nullptr; - if ( eventObj == nullptr ) { +SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( Event ) +{ + static idSWFScriptObject* eventObj = nullptr; + if( eventObj == nullptr ) + { eventObj = idSWFScriptObject::Alloc( ); - idSWFScriptObject *eventParms = idSWFScriptObject::Alloc( ); + idSWFScriptObject* eventParms = idSWFScriptObject::Alloc( ); eventParms->Set( "type", "Event" ); eventObj->Set( "[Event]", eventParms ); - + //constants eventObj->Set( "ACTIVATE", "activate" ); eventObj->Set( "ADDED", "added" ); @@ -141,16 +144,18 @@ SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( Event ) { return eventObj; } -SWF_EVENTDISPATCHER_FUNCTION_DEFINE( addEventListener ) +SWF_EVENTDISPATCHER_FUNCTION_DEFINE( addEventListener ) { SWF_EVENTDISPATCHER_PTHIS_FUNC( "addEventListener" ); - swfNamedVar_t * dispatcher = thisObject->GetVariable("__eventDispatcher__",true); - - if (dispatcher->value.IsUndefined() ) - dispatcher->value.SetObject(idSWFScriptObject::Alloc()); + swfNamedVar_t* dispatcher = thisObject->GetVariable( "__eventDispatcher__", true ); + + if( dispatcher->value.IsUndefined() ) + { + dispatcher->value.SetObject( idSWFScriptObject::Alloc() ); + } - dispatcher->value.GetObject()->Set(parms[1].ToString(),parms[0]); - common->DPrintf("{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(),parms[1].ToString().c_str(),parms[0].ToString().c_str()); + dispatcher->value.GetObject()->Set( parms[1].ToString(), parms[0] ); + common->DPrintf( "{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(), parms[1].ToString().c_str(), parms[0].ToString().c_str() ); //add listener return idSWFScriptVar( ); } diff --git a/neo/swf/SWF_EventDispatcher.h b/neo/swf/SWF_EventDispatcher.h index 8cbae79613..674cee117e 100644 --- a/neo/swf/SWF_EventDispatcher.h +++ b/neo/swf/SWF_EventDispatcher.h @@ -35,7 +35,8 @@ If you have questions concerning this license or the applicable additional terms #include "swf.h" #include "SWF_Abc.h" -class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject { +class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject +{ public: idSWFScriptObject_EventDispatcherPrototype( ); #define SWF_EVENTDISPATCHER_FUNCTION_DECLARE( x ) \ diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 65b1980ce7..5286f6a539 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -28,29 +28,33 @@ If you have questions concerning this license or the applicable additional terms */ #include "precompiled.h" #pragma hdrstop -idSWFScriptObject* GetMouseEventDispatcher( idSWFScriptObject *object ) { - idSWFScriptObject *dispatcher = nullptr; - if ( object->HasValidProperty( "__eventDispatcher__" ) ) { +idSWFScriptObject* GetMouseEventDispatcher( idSWFScriptObject* object ) +{ + idSWFScriptObject* dispatcher = nullptr; + if( object->HasValidProperty( "__eventDispatcher__" ) ) + { dispatcher = object->Get( "__eventDispatcher__" ).GetObject( ); - if ( dispatcher->HasValidProperty( "click" ) - || dispatcher->HasValidProperty( "contextMenu" ) - || dispatcher->HasValidProperty( "doubleClick" ) - || dispatcher->HasValidProperty( "middleClick" ) - || dispatcher->HasValidProperty( "middleMouseDown" ) - || dispatcher->HasValidProperty( "middleMouseUp" ) - || dispatcher->HasValidProperty( "mouseDown" ) - || dispatcher->HasValidProperty( "mouseMove" ) - || dispatcher->HasValidProperty( "mouseOut" ) - || dispatcher->HasValidProperty( "mouseOver" ) - || dispatcher->HasValidProperty( "mouseUp" ) - || dispatcher->HasValidProperty( "mouseWheel" ) - || dispatcher->HasValidProperty( "releaseOutside" ) - || dispatcher->HasValidProperty( "rightClick" ) - || dispatcher->HasValidProperty( "rightMouseDown" ) - || dispatcher->HasValidProperty( "rightMouseUp" ) - || dispatcher->HasValidProperty( "rollOut" ) - || dispatcher->HasValidProperty( "rollOver" ) ) + if( dispatcher->HasValidProperty( "click" ) + || dispatcher->HasValidProperty( "contextMenu" ) + || dispatcher->HasValidProperty( "doubleClick" ) + || dispatcher->HasValidProperty( "middleClick" ) + || dispatcher->HasValidProperty( "middleMouseDown" ) + || dispatcher->HasValidProperty( "middleMouseUp" ) + || dispatcher->HasValidProperty( "mouseDown" ) + || dispatcher->HasValidProperty( "mouseMove" ) + || dispatcher->HasValidProperty( "mouseOut" ) + || dispatcher->HasValidProperty( "mouseOver" ) + || dispatcher->HasValidProperty( "mouseUp" ) + || dispatcher->HasValidProperty( "mouseWheel" ) + || dispatcher->HasValidProperty( "releaseOutside" ) + || dispatcher->HasValidProperty( "rightClick" ) + || dispatcher->HasValidProperty( "rightMouseDown" ) + || dispatcher->HasValidProperty( "rightMouseUp" ) + || dispatcher->HasValidProperty( "rollOut" ) + || dispatcher->HasValidProperty( "rollOver" ) ) + { return dispatcher; + } } return nullptr; } @@ -76,20 +80,21 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw { return NULL; } - - idSWFScriptObject * dispatcher = GetMouseEventDispatcher( spriteInstance->scriptObject ); - if (dispatcher!=nullptr) { - parentObject = spriteInstance->scriptObject; - }else + idSWFScriptObject* dispatcher = GetMouseEventDispatcher( spriteInstance->scriptObject ); + + if( dispatcher != nullptr ) { - if ( spriteInstance->scriptObject->HasValidProperty( "onRelease" ) - || spriteInstance->scriptObject->HasValidProperty( "onPress" ) - || spriteInstance->scriptObject->HasValidProperty( "onRollOver" ) - || spriteInstance->scriptObject->HasValidProperty( "onRollOut" ) - || spriteInstance->scriptObject->HasValidProperty( "onDrag" ) - || spriteInstance->scriptObject->HasValidProperty( "onDrag" ) - ) + parentObject = spriteInstance->scriptObject; + } + else + { + if( spriteInstance->scriptObject->HasValidProperty( "onRelease" ) + || spriteInstance->scriptObject->HasValidProperty( "onPress" ) + || spriteInstance->scriptObject->HasValidProperty( "onRollOver" ) + || spriteInstance->scriptObject->HasValidProperty( "onRollOut" ) + || spriteInstance->scriptObject->HasValidProperty( "onDrag" ) + ) { parentObject = spriteInstance->scriptObject; } @@ -156,29 +161,30 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw else if( entry->type == SWF_DICT_MORPH ) { // FIXME: this should be roughly the same as SWF_DICT_SHAPE - - //} else if( entry->type == SWF_DICT_TEXT ) - //{ + + //} else if( entry->type == SWF_DICT_TEXT ) + //{ // FIXME: this should be roughly the same as SWF_DICT_SHAPE } - else if( entry->type == SWF_DICT_EDITTEXT || entry->type == SWF_DICT_TEXT) + else if( entry->type == SWF_DICT_EDITTEXT || entry->type == SWF_DICT_TEXT ) { idSWFScriptObject* editObject = NULL; - idSWFScriptObject * textdispatcher = nullptr; - if ( display.textInstance ) + idSWFScriptObject* textdispatcher = nullptr; + if( display.textInstance ) { dispatcher = GetMouseEventDispatcher( &display.textInstance->scriptObject ); } - if ( dispatcher!=nullptr ) + if( dispatcher != nullptr ) { editObject = &display.textInstance->scriptObject; - }else if ( display.textInstance && ( display.textInstance->scriptObject.HasProperty( "onRelease" ) || display.textInstance->scriptObject.HasProperty( "onPress" ) ) ) + } + else if( display.textInstance && ( display.textInstance->scriptObject.HasProperty( "onRelease" ) || display.textInstance->scriptObject.HasProperty( "onPress" ) ) ) { // if the edit box itself can be clicked, then we want to return it when it's clicked on editObject = &display.textInstance->scriptObject; } - else if ( !dispatcher && parentObject != NULL ) + else if( !dispatcher && parentObject != NULL ) { // otherwise, we want to return the parent object editObject = parentObject; @@ -189,7 +195,7 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw continue; } - if(!display.textInstance || display.textInstance->text.IsEmpty() ) + if( !display.textInstance || display.textInstance->text.IsEmpty() ) { continue; } @@ -297,7 +303,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) mouseEnabled = true; idSWFScriptVar var; idSWFScriptVar eventDispatcher = mainspriteInstance->GetScriptObject()->Get( "__eventDispatcher__" ); - if ( event->evValue2 ) + if( event->evValue2 ) { idSWFScriptVar waitInput = globals->Get( "waitInput" ); @@ -322,25 +328,27 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) eventDispatcher = hitObject->Get( "__eventDispatcher__" ); - if (!eventDispatcher.IsUndefined() && !var.IsFunction()) + if( !eventDispatcher.IsUndefined() && !var.IsFunction() ) { var = eventDispatcher.GetObject( )->Get( "click" ); - if ( !var.IsFunction( ) ) + if( !var.IsFunction( ) ) + { var = eventDispatcher.GetObject( )->Get( "mouseDown" ); + } } - if ( var.IsFunction( ) ) + if( var.IsFunction( ) ) { idSWFScriptVar eventArg; - auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); eventArg.SetObject( idSWFScriptObject::Alloc( ) ); eventArg.GetObject( )->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) { - ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); } var.GetFunction( )->Call( hitObject, parms ); parms.Clear( ); @@ -348,7 +356,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) } var = hitObject->Get( "onPress" ); - if ( var.IsFunction( ) ) + if( var.IsFunction( ) ) { idSWFParmList parms; parms.Append( event->inputDevice ); @@ -374,29 +382,30 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) parms.Append( hitObject ); Invoke( "setHitObject", parms ); - } else + } + else { - if ( mouseObject ) + if( mouseObject ) { eventDispatcher = mouseObject->Get( "__eventDispatcher__" ); - if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) { var = eventDispatcher.GetObject( )->Get( "mouseUp" ); } - if ( var.IsFunction( ) ) + if( var.IsFunction( ) ) { idSWFScriptVar eventArg; - auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); eventArg.SetObject( idSWFScriptObject::Alloc( ) ); eventArg.GetObject( )->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) { - ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); } var.GetFunction( )->Call( mouseObject, parms ); parms.Clear( ); @@ -591,33 +600,39 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) } idSWFScriptVar eventDispatcher; - if ( hitObject != hoverObject ) { - + if( hitObject != hoverObject ) + { + // First check to see if we should call onRollOut on our previous hoverObject if( hoverObject != NULL ) { idSWFScriptVar var = hoverObject->Get( "onRollOut" ); eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); - if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) { var = eventDispatcher.GetObject( )->Get( "mouseOut" ); - if ( var.IsFunction( ) ) { + if( var.IsFunction( ) ) + { idSWFScriptVar eventArg; - auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); eventArg.SetObject( idSWFScriptObject::Alloc( ) ); eventArg.GetObject( )->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) - ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + { + ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + } var.GetFunction( )->Call( hoverObject, parms ); parms.Clear( ); retVal = true; } - }else if ( var.IsFunction( ) ) { + } + else if( var.IsFunction( ) ) + { var.GetFunction( )->Call( hoverObject, idSWFParmList( ) ); retVal = true; } @@ -632,26 +647,30 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) idSWFScriptVar var = hitObject->Get( "onRollOver" ); eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); - if ( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) { var = eventDispatcher.GetObject( )->Get( "mouseOver" ); - if (var.IsFunction() ) + if( var.IsFunction() ) { idSWFScriptVar eventArg; - auto *eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) + ->Get( "MouseEvent" ).GetObject( ) + ->Get( "[MouseEvent]" ).GetObject( ); eventArg.SetObject( idSWFScriptObject::Alloc( ) ); eventArg.GetObject( )->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if ( !( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Num( ) ) - ( ( idSWFScriptFunction_Script * ) var.GetFunction( ) )->GetScope( )->Append( globals ); + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + { + ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + } var.GetFunction( )->Call( hoverObject, parms ); parms.Clear( ); retVal = true; } - } else if ( var.IsFunction( ) ) { + } + else if( var.IsFunction( ) ) + { var.GetFunction( )->Call( hitObject, idSWFParmList( ) ); retVal = true; } diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index f25d2f5c55..3e1ed1acc5 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -8,23 +8,28 @@ //#include "SWF_ScriptFunction.h" //#include "framework/Common.h" -inline int32 readS24( const byte *pc ) { - return ((uint16_t*)pc)[0] | ((int8_t*)pc)[2]<<16; +inline int32 readS24( const byte* pc ) +{ + return ( ( uint16_t* )pc )[0] | ( ( int8_t* )pc )[2] << 16; } -inline uint32 readU30( const uint8_t *&pc ) { +inline uint32 readU30( const uint8_t*& pc ) +{ uint32 result = 0; - for ( int i = 0; i < 5; i++ ) { + for( int i = 0; i < 5; i++ ) + { byte b = *pc++; result |= ( b & 0x7F ) << ( 7 * i ); - if ( ( b & 0x80 ) == 0 ) { + if( ( b & 0x80 ) == 0 ) + { return result; } } return result; } -const AbcOpcodeInfo opcodeInfo[] = { +const AbcOpcodeInfo opcodeInfo[] = +{ // For stack movement ("stk") only constant movement is accounted for; variable movement, // as for arguments to CALL, CONSTRUCT, APPLYTYPE, et al, and for run-time parts of // names, must be handled separately. @@ -39,328 +44,362 @@ const AbcOpcodeInfo opcodeInfo[] = { #undef ABC_OP_F }; -void debugfile(SWF_AbcFile * file, idSWFBitStream &bitstream ) +void debugfile( SWF_AbcFile* file, idSWFBitStream& bitstream ) { - common->Printf(" debugfile %s\n",file->constant_pool.utf8Strings[bitstream.ReadEncodedU32()].c_str()); + common->Printf( " debugfile %s\n", file->constant_pool.utf8Strings[bitstream.ReadEncodedU32()].c_str() ); } -void debugline(SWF_AbcFile * file, idSWFBitStream &bitstream ) +void debugline( SWF_AbcFile* file, idSWFBitStream& bitstream ) { - common->Printf(" debugline %i\n",(int)bitstream.ReadEncodedU32()); + common->Printf( " debugline %i\n", ( int )bitstream.ReadEncodedU32() ); } -void swf_PrintStream(SWF_AbcFile * file, idSWFBitStream &bitstream ) { +void swf_PrintStream( SWF_AbcFile* file, idSWFBitStream& bitstream ) +{ //(case.*OP_)([A-Za-z0-9]*_?[A-Za-z0-9]*)(.*\n)(.*) idSWFStack stack; static idList codeMap; idStr type; - const AbcOpcodeInfo * info = nullptr; - while ( bitstream.Tell() < bitstream.Length() ) { + const AbcOpcodeInfo* info = nullptr; + while( bitstream.Tell() < bitstream.Length() ) + { #define DoWordCode( n ) case OP_##n: type = #n; info = &opcodeInfo[opCode]; break; #define ExecWordCode( n ) case OP_##n: type = #n; info = &opcodeInfo[opCode]; n(file,bitstream); continue; - SWFAbcOpcode opCode = (SWFAbcOpcode) bitstream.ReadU8(); - switch ( opCode ) { - DoWordCode ( bkpt ); - DoWordCode ( nop ); - DoWordCode ( throw ); - DoWordCode ( getsuper ); - DoWordCode ( setsuper ); - DoWordCode ( dxns ); - DoWordCode ( dxnslate ); - DoWordCode ( kill ); - DoWordCode ( label ); - DoWordCode ( ifnlt ); - DoWordCode ( ifnle ); - DoWordCode ( ifngt ); - DoWordCode ( ifnge ); - DoWordCode ( jump ); - DoWordCode ( iftrue ); - DoWordCode ( iffalse ); - DoWordCode ( ifeq ); - DoWordCode ( ifne ); - DoWordCode ( iflt ); - DoWordCode ( ifle ); - DoWordCode ( ifgt ); - DoWordCode ( ifge ); - DoWordCode ( ifstricteq ); - DoWordCode ( ifstrictne ); - DoWordCode ( lookupswitch ); - DoWordCode ( pushwith ); - DoWordCode ( popscope ); - DoWordCode ( nextname ); - DoWordCode ( hasnext ); - DoWordCode ( pushnull ); - DoWordCode ( pushundefined ); - DoWordCode ( DISABLED_pushfloat ); - DoWordCode ( nextvalue ); - DoWordCode ( pushbyte ); - DoWordCode ( pushshort ); - DoWordCode ( pushtrue ); - DoWordCode ( pushfalse ); - DoWordCode ( pushnan ); - DoWordCode ( pop ); - DoWordCode ( dup ); - DoWordCode ( swap ); - DoWordCode ( pushstring ); - DoWordCode ( pushint ); - DoWordCode ( pushuint ); - DoWordCode ( pushdouble ); - DoWordCode ( pushscope ); - DoWordCode ( pushnamespace ); - DoWordCode ( hasnext2 ); - DoWordCode ( lix8 ); - DoWordCode ( lix16 ); - DoWordCode ( li8 ); - DoWordCode ( li16 ); - DoWordCode ( li32 ); - DoWordCode ( lf32 ); - DoWordCode ( lf64 ); - DoWordCode ( si8 ); - DoWordCode ( si16 ); - DoWordCode ( si32 ); - DoWordCode ( sf32 ); - DoWordCode ( sf64 ); - DoWordCode ( newfunction ); - DoWordCode ( call ); - DoWordCode ( construct ); - DoWordCode ( callmethod ); - DoWordCode ( callstatic ); - DoWordCode ( callsuper ); - DoWordCode ( callproperty ); - DoWordCode ( returnvoid ); - DoWordCode ( returnvalue ); - DoWordCode ( constructsuper ); - DoWordCode ( constructprop ); - DoWordCode ( callsuperid ); - DoWordCode ( callproplex ); - DoWordCode ( callinterface ); - DoWordCode ( callsupervoid ); - DoWordCode ( callpropvoid ); - DoWordCode ( sxi1 ); - DoWordCode ( sxi8 ); - DoWordCode ( sxi16 ); - DoWordCode ( applytype ); - DoWordCode ( DISABLED_pushfloat4 ); - DoWordCode ( newobject ); - DoWordCode ( newarray ); - DoWordCode ( newactivation ); - DoWordCode ( newclass ); - DoWordCode ( getdescendants ); - DoWordCode ( newcatch ); - DoWordCode ( findpropglobalstrict ); - DoWordCode ( findpropglobal ); - DoWordCode ( findpropstrict ); - DoWordCode ( findproperty ); - DoWordCode ( finddef ); - DoWordCode ( getlex ); - DoWordCode ( setproperty ); - DoWordCode ( getlocal ); - DoWordCode ( setlocal ); - DoWordCode ( getglobalscope ); - DoWordCode ( getscopeobject ); - DoWordCode ( getproperty ); - DoWordCode ( getouterscope ); - DoWordCode ( initproperty ); - DoWordCode( deleteproperty ); - DoWordCode ( getslot ); - DoWordCode ( setslot ); - DoWordCode ( getglobalslot ); - DoWordCode ( setglobalslot ); - DoWordCode ( convert_s ); - DoWordCode ( esc_xelem ); - DoWordCode ( esc_xattr ); - DoWordCode ( convert_i ); - DoWordCode ( convert_u ); - DoWordCode ( convert_d ); - DoWordCode ( convert_b ); - DoWordCode ( convert_o ); - DoWordCode ( checkfilter ); - //DoWordCode ( DISABLED_convert ); - //DoWordCode ( DISABLED_unplus ); - //DoWordCode ( DISABLED_convert ); - DoWordCode ( coerce ); - DoWordCode ( coerce_b ); - DoWordCode ( coerce_a ); - DoWordCode ( coerce_i ); - DoWordCode ( coerce_d ); - DoWordCode ( coerce_s ); - DoWordCode ( astype ); - DoWordCode ( astypelate ); - DoWordCode ( coerce_u ); - DoWordCode ( coerce_o ); - DoWordCode ( negate ); - DoWordCode ( increment ); - DoWordCode ( inclocal ); - DoWordCode ( decrement ); - DoWordCode ( declocal ); - DoWordCode ( typeof ); - DoWordCode ( not ); - DoWordCode ( bitnot ); - DoWordCode ( add ); - DoWordCode ( subtract ); - DoWordCode ( multiply ); - DoWordCode ( divide ); - DoWordCode ( modulo ); - DoWordCode ( lshift ); - DoWordCode ( rshift ); - DoWordCode ( urshift ); - DoWordCode ( bitand ); - DoWordCode ( bitor ); - DoWordCode ( bitxor ); - DoWordCode ( equals ); - DoWordCode ( strictequals ); - DoWordCode ( lessthan ); - DoWordCode ( lessequals ); - DoWordCode ( greaterthan ); - DoWordCode ( greaterequals ); - DoWordCode ( instanceof ); - DoWordCode ( istype ); - DoWordCode ( istypelate ); - DoWordCode ( in ); - DoWordCode ( increment_i ); - DoWordCode ( decrement_i ); - DoWordCode ( inclocal_i ); - DoWordCode ( declocal_i ); - DoWordCode ( negate_i ); - DoWordCode ( add_i ); - DoWordCode ( subtract_i ); - DoWordCode ( multiply_i ); - DoWordCode ( getlocal0 ); - DoWordCode ( getlocal1 ); - DoWordCode ( getlocal2 ); - DoWordCode ( getlocal3 ); - DoWordCode ( setlocal0 ); - DoWordCode ( setlocal1 ); - DoWordCode ( setlocal2 ); - DoWordCode ( setlocal3 ); - DoWordCode ( debug ); - ExecWordCode ( debugline ); - ExecWordCode ( debugfile ); - DoWordCode ( bkptline ); - DoWordCode ( timestamp ); - DoWordCode ( restargc ); - DoWordCode ( restarg ); - default: - common->Printf( "default %s %s\n", type.c_str( ) ,info ? info->name:"Empty"); + SWFAbcOpcode opCode = ( SWFAbcOpcode ) bitstream.ReadU8(); + switch( opCode ) + { + DoWordCode( bkpt ); + DoWordCode( nop ); + DoWordCode( throw ); + DoWordCode( getsuper ); + DoWordCode( setsuper ); + DoWordCode( dxns ); + DoWordCode( dxnslate ); + DoWordCode( kill ); + DoWordCode( label ); + DoWordCode( ifnlt ); + DoWordCode( ifnle ); + DoWordCode( ifngt ); + DoWordCode( ifnge ); + DoWordCode( jump ); + DoWordCode( iftrue ); + DoWordCode( iffalse ); + DoWordCode( ifeq ); + DoWordCode( ifne ); + DoWordCode( iflt ); + DoWordCode( ifle ); + DoWordCode( ifgt ); + DoWordCode( ifge ); + DoWordCode( ifstricteq ); + DoWordCode( ifstrictne ); + DoWordCode( lookupswitch ); + DoWordCode( pushwith ); + DoWordCode( popscope ); + DoWordCode( nextname ); + DoWordCode( hasnext ); + DoWordCode( pushnull ); + DoWordCode( pushundefined ); + DoWordCode( DISABLED_pushfloat ); + DoWordCode( nextvalue ); + DoWordCode( pushbyte ); + DoWordCode( pushshort ); + DoWordCode( pushtrue ); + DoWordCode( pushfalse ); + DoWordCode( pushnan ); + DoWordCode( pop ); + DoWordCode( dup ); + DoWordCode( swap ); + DoWordCode( pushstring ); + DoWordCode( pushint ); + DoWordCode( pushuint ); + DoWordCode( pushdouble ); + DoWordCode( pushscope ); + DoWordCode( pushnamespace ); + DoWordCode( hasnext2 ); + DoWordCode( lix8 ); + DoWordCode( lix16 ); + DoWordCode( li8 ); + DoWordCode( li16 ); + DoWordCode( li32 ); + DoWordCode( lf32 ); + DoWordCode( lf64 ); + DoWordCode( si8 ); + DoWordCode( si16 ); + DoWordCode( si32 ); + DoWordCode( sf32 ); + DoWordCode( sf64 ); + DoWordCode( newfunction ); + DoWordCode( call ); + DoWordCode( construct ); + DoWordCode( callmethod ); + DoWordCode( callstatic ); + DoWordCode( callsuper ); + DoWordCode( callproperty ); + DoWordCode( returnvoid ); + DoWordCode( returnvalue ); + DoWordCode( constructsuper ); + DoWordCode( constructprop ); + DoWordCode( callsuperid ); + DoWordCode( callproplex ); + DoWordCode( callinterface ); + DoWordCode( callsupervoid ); + DoWordCode( callpropvoid ); + DoWordCode( sxi1 ); + DoWordCode( sxi8 ); + DoWordCode( sxi16 ); + DoWordCode( applytype ); + DoWordCode( DISABLED_pushfloat4 ); + DoWordCode( newobject ); + DoWordCode( newarray ); + DoWordCode( newactivation ); + DoWordCode( newclass ); + DoWordCode( getdescendants ); + DoWordCode( newcatch ); + DoWordCode( findpropglobalstrict ); + DoWordCode( findpropglobal ); + DoWordCode( findpropstrict ); + DoWordCode( findproperty ); + DoWordCode( finddef ); + DoWordCode( getlex ); + DoWordCode( setproperty ); + DoWordCode( getlocal ); + DoWordCode( setlocal ); + DoWordCode( getglobalscope ); + DoWordCode( getscopeobject ); + DoWordCode( getproperty ); + DoWordCode( getouterscope ); + DoWordCode( initproperty ); + DoWordCode( deleteproperty ); + DoWordCode( getslot ); + DoWordCode( setslot ); + DoWordCode( getglobalslot ); + DoWordCode( setglobalslot ); + DoWordCode( convert_s ); + DoWordCode( esc_xelem ); + DoWordCode( esc_xattr ); + DoWordCode( convert_i ); + DoWordCode( convert_u ); + DoWordCode( convert_d ); + DoWordCode( convert_b ); + DoWordCode( convert_o ); + DoWordCode( checkfilter ); + //DoWordCode ( DISABLED_convert ); + //DoWordCode ( DISABLED_unplus ); + //DoWordCode ( DISABLED_convert ); + DoWordCode( coerce ); + DoWordCode( coerce_b ); + DoWordCode( coerce_a ); + DoWordCode( coerce_i ); + DoWordCode( coerce_d ); + DoWordCode( coerce_s ); + DoWordCode( astype ); + DoWordCode( astypelate ); + DoWordCode( coerce_u ); + DoWordCode( coerce_o ); + DoWordCode( negate ); + DoWordCode( increment ); + DoWordCode( inclocal ); + DoWordCode( decrement ); + DoWordCode( declocal ); + DoWordCode( typeof ); + DoWordCode( not ); + DoWordCode( bitnot ); + DoWordCode( add ); + DoWordCode( subtract ); + DoWordCode( multiply ); + DoWordCode( divide ); + DoWordCode( modulo ); + DoWordCode( lshift ); + DoWordCode( rshift ); + DoWordCode( urshift ); + DoWordCode( bitand ); + DoWordCode( bitor ); + DoWordCode( bitxor ); + DoWordCode( equals ); + DoWordCode( strictequals ); + DoWordCode( lessthan ); + DoWordCode( lessequals ); + DoWordCode( greaterthan ); + DoWordCode( greaterequals ); + DoWordCode( instanceof ); + DoWordCode( istype ); + DoWordCode( istypelate ); + DoWordCode( in ); + DoWordCode( increment_i ); + DoWordCode( decrement_i ); + DoWordCode( inclocal_i ); + DoWordCode( declocal_i ); + DoWordCode( negate_i ); + DoWordCode( add_i ); + DoWordCode( subtract_i ); + DoWordCode( multiply_i ); + DoWordCode( getlocal0 ); + DoWordCode( getlocal1 ); + DoWordCode( getlocal2 ); + DoWordCode( getlocal3 ); + DoWordCode( setlocal0 ); + DoWordCode( setlocal1 ); + DoWordCode( setlocal2 ); + DoWordCode( setlocal3 ); + DoWordCode( debug ); + ExecWordCode( debugline ); + ExecWordCode( debugfile ); + DoWordCode( bkptline ); + DoWordCode( timestamp ); + DoWordCode( restargc ); + DoWordCode( restarg ); + default: + common->Printf( "default %s %s\n", type.c_str( ) , info ? info->name : "Empty" ); + } + static const char* tabs[] = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; + if( info && info->operandCount > 0 ) + { + bitstream.ReadData( info->operandCount ); } - static const char * tabs[] = { " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "}; - if ( info && info->operandCount > 0 ) - bitstream.ReadData(info->operandCount); common->Printf( " %s %s o %s%i \t s %s%i \n" , - info ? info->name:type.c_str( ), - tabs[int(18 - (int(idStr::Length(info->name))))], - info->operandCount > 0 ? "^2" : "^1" , - info->operandCount, - info->stack < 0 ? "^2" : "^1", - info->stack - ); + info ? info->name : type.c_str( ), + tabs[int( 18 - ( int( idStr::Length( info->name ) ) ) )], + info->operandCount > 0 ? "^2" : "^1" , + info->operandCount, + info->stack < 0 ? "^2" : "^1", + info->stack + ); } bitstream.Rewind(); #undef DoWordCode #undef ExecWordCode } -void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) +void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { - const auto &cp = file->constant_pool; - const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& cp = file->constant_pool; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; //search up scope stack. - for ( int i = scope.Num( ) - 1; i >= 0; i-- ) { - auto *s = scope[i]; - while ( s ) - if ( s->HasProperty( propName->c_str( ) ) ) { + for( int i = scope.Num( ) - 1; i >= 0; i-- ) + { + auto* s = scope[i]; + while( s ) + if( s->HasProperty( propName->c_str( ) ) ) + { stack.Alloc( ) = s->Get( propName->c_str( ) ); return; - } else if ( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype( ) ) + } + else if( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype( ) ) + { s = s->GetPrototype( )->GetPrototype( ); + } else + { s = NULL; + } } - common->Warning("idSWFScriptFunction_Script::findpropstrict cant find %s",propName->c_str()); + common->Warning( "idSWFScriptFunction_Script::findpropstrict cant find %s", propName->c_str() ); //search method closure, which is the stack up until a method call? } -void idSWFScriptFunction_Script::getlex( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) +void idSWFScriptFunction_Script::getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { - const auto &cp = file->constant_pool; - const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& cp = file->constant_pool; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; //search up scope stack. - for ( int i = scope.Num( ) - 1; i >= 0; i-- ) { - auto *s = scope[i]; - while ( s ) - if ( s->HasProperty( propName->c_str( ) )) + for( int i = scope.Num( ) - 1; i >= 0; i-- ) + { + auto* s = scope[i]; + while( s ) + if( s->HasProperty( propName->c_str( ) ) ) { stack.Alloc( ) = s->Get( propName->c_str( ) ); return; - }else if (s->GetPrototype( ) && s->GetPrototype( )->GetPrototype() ) + } + else if( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype() ) + { s = s->GetPrototype( )->GetPrototype(); + } else + { s = NULL; + } } } -void idSWFScriptFunction_Script::getscopeobject( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { +void idSWFScriptFunction_Script::getscopeobject( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ uint8 index = bitstream.ReadEncodedU32(); stack.Alloc() = scope[scope.Num() - index]; } -void idSWFScriptFunction_Script::pushscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { - if (stack.Num() > 0) - { - if ( stack.A().IsObject() ) +void idSWFScriptFunction_Script::pushscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ + if( stack.Num() > 0 ) + { + if( stack.A().IsObject() ) + { scope.Alloc() = stack.A().GetObject(); + } else - common->DWarning( "tried to push a non object onto scope"); - stack.Pop(1); + { + common->DWarning( "tried to push a non object onto scope" ); + } + stack.Pop( 1 ); } } -void idSWFScriptFunction_Script::popscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { +void idSWFScriptFunction_Script::popscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ scope.SetNum( scope.Num() - 1 ); } -void idSWFScriptFunction_Script::getlocal0(SWF_AbcFile* file, idSWFStack &stack, idSWFBitStream &bitstream ) { +void idSWFScriptFunction_Script::getlocal0( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ stack.Alloc() = registers[0]; } -//The class's static initializer will be run when the newclass instruction +//The class's static initializer will be run when the newclass instruction // is executed on the class_info entry for the class. -void idSWFScriptFunction_Script::newclass( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { - const auto &ci = file->classes[bitstream.ReadEncodedU32( )]; - idSWFScriptVar base = stack.A(); stack.Pop(1); +void idSWFScriptFunction_Script::newclass( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ + const auto& ci = file->classes[bitstream.ReadEncodedU32( )]; + idSWFScriptVar base = stack.A(); + stack.Pop( 1 ); idSWFScriptVar* thisObj = ®isters[0]; //find static intializer. int a = 1; } -void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ) { - const auto &cp = file->constant_pool; - const auto &mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; +void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ + const auto& cp = file->constant_pool; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; uint32 arg_count = bitstream.ReadEncodedU32(); - idSWFParmList parms(arg_count); + idSWFParmList parms( arg_count ); - for ( int i = 0; i < parms.Num( ); i++ ) { + for( int i = 0; i < parms.Num( ); i++ ) + { parms[i] = stack.A( ); stack.Pop( 1 ); } - idSWFScriptVar & item = stack.A(); - if (item.IsFunction()) - item.GetFunction()->Call(registers[0].GetObject(),parms); + idSWFScriptVar& item = stack.A(); + if( item.IsFunction() ) + { + item.GetFunction()->Call( registers[0].GetObject(), parms ); + } else if( item.IsObject() ) { auto func = item.GetObject()->Get( funcName->c_str() ); - if ( func.IsFunction( ) ) + if( func.IsFunction( ) ) { - if (!((idSWFScriptFunction_Script*)func.GetFunction())->GetScope()->Num()) - ((idSWFScriptFunction_Script*)func.GetFunction())->SetScope(*GetScope()); + if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )func.GetFunction() )->SetScope( *GetScope() ); + } func.GetFunction( )->Call( item.GetObject(), parms ); } } - stack.Pop(1); + stack.Pop( 1 ); } /* @@ -368,419 +407,475 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile *file, idSWFStack &st idSWFScriptFunction_Script::RunAbc bytecode ======================== */ -idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject *thisObject, idSWFStack &stack, idSWFBitStream &bitstream ) { +idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream ) +{ static int abcCallstackLevel = -1; - idSWFSpriteInstance *thisSprite = thisObject->GetSprite( ); - idSWFSpriteInstance *currentTarget = thisSprite; + idSWFSpriteInstance* thisSprite = thisObject->GetSprite( ); + idSWFSpriteInstance* currentTarget = thisSprite; assert( abcFile ); abcCallstackLevel++; - if ( currentTarget == NULL ) { + if( currentTarget == NULL ) + { thisSprite = currentTarget = defaultSprite; } - while ( bitstream.Tell( ) < bitstream.Length( ) ) { + while( bitstream.Tell( ) < bitstream.Length( ) ) + { #define ExecWordCode( n ) case OP_##n: n(abcFile,stack,bitstream); continue; #define InlineWordCode( n ) case OP_##n: - SWFAbcOpcode opCode = (SWFAbcOpcode) bitstream.ReadU8(); - - switch ( opCode ) { - //ExecWordCode ( bkpt ); - //ExecWordCode ( nop ); - //ExecWordCode ( throw ); - //ExecWordCode ( getsuper ); - //ExecWordCode ( setsuper ); - //ExecWordCode ( dxns ); - //ExecWordCode ( dxnslate ); - //ExecWordCode ( kill ); - //ExecWordCode ( label ); - //ExecWordCode ( ifnlt ); - //ExecWordCode ( ifnle ); - //ExecWordCode ( ifngt ); - //ExecWordCode ( ifnge ); - //ExecWordCode ( jump ); - //ExecWordCode ( iftrue ); - //ExecWordCode ( iffalse ); - //ExecWordCode ( ifeq ); - //ExecWordCode ( ifne ); - //ExecWordCode ( iflt ); - //ExecWordCode ( ifle ); - //ExecWordCode ( ifgt ); - //ExecWordCode ( ifge ); - //ExecWordCode ( ifstricteq ); - //ExecWordCode ( ifstrictne ); - //ExecWordCode ( lookupswitch ); - //ExecWordCode ( pushwith ); - ExecWordCode ( popscope ); - //ExecWordCode ( nextname ); - //ExecWordCode ( hasnext ); - InlineWordCode( pushnull ) + SWFAbcOpcode opCode = ( SWFAbcOpcode ) bitstream.ReadU8(); + + switch( opCode ) + { + //ExecWordCode ( bkpt ); + //ExecWordCode ( nop ); + //ExecWordCode ( throw ); + //ExecWordCode ( getsuper ); + //ExecWordCode ( setsuper ); + //ExecWordCode ( dxns ); + //ExecWordCode ( dxnslate ); + //ExecWordCode ( kill ); + //ExecWordCode ( label ); + //ExecWordCode ( ifnlt ); + //ExecWordCode ( ifnle ); + //ExecWordCode ( ifngt ); + //ExecWordCode ( ifnge ); + //ExecWordCode ( jump ); + //ExecWordCode ( iftrue ); + //ExecWordCode ( iffalse ); + //ExecWordCode ( ifeq ); + //ExecWordCode ( ifne ); + //ExecWordCode ( iflt ); + //ExecWordCode ( ifle ); + //ExecWordCode ( ifgt ); + //ExecWordCode ( ifge ); + //ExecWordCode ( ifstricteq ); + //ExecWordCode ( ifstrictne ); + //ExecWordCode ( lookupswitch ); + //ExecWordCode ( pushwith ); + ExecWordCode( popscope ); + //ExecWordCode ( nextname ); + //ExecWordCode ( hasnext ); + InlineWordCode( pushnull ) stack.Append( idSWFScriptVar( NULL ) ); - continue; - //ExecWordCode ( pushundefined ); - InlineWordCode( pushundefined ) + continue; + //ExecWordCode ( pushundefined ); + InlineWordCode( pushundefined ) stack.Append( idSWFScriptVar( ) ); - continue; - //ExecWordCode ( nextvalue ); - InlineWordCode ( pushbyte ) - stack.Append( idSWFScriptVar((int)bitstream.ReadU8())); continue; - InlineWordCode ( pushshort ) - stack.Append( idSWFScriptVar((int)bitstream.ReadEncodedU32( ))); - continue; - InlineWordCode ( pushtrue ) + //ExecWordCode ( nextvalue ); + InlineWordCode( pushbyte ) + stack.Append( idSWFScriptVar( ( int )bitstream.ReadU8() ) ); + continue; + InlineWordCode( pushshort ) + stack.Append( idSWFScriptVar( ( int )bitstream.ReadEncodedU32( ) ) ); + continue; + InlineWordCode( pushtrue ) stack.Append( idSWFScriptVar( true ) ); continue; - InlineWordCode ( pushfalse ) + InlineWordCode( pushfalse ) stack.Append( idSWFScriptVar( false ) ); continue; - //ExecWordCode ( pushnan ); - InlineWordCode ( pop ) - stack.Pop(1); - continue; - InlineWordCode ( dup ) - stack.Alloc() = idSWFScriptVar(stack.A()); - continue; - InlineWordCode( swap ) - common->FatalError("swap not implemented"); - continue; - InlineWordCode ( pushstring ) - { - const auto &cp = abcFile->constant_pool.utf8Strings; - const auto &mn = cp[bitstream.ReadEncodedU32( )]; - stack.Append( idSWFScriptString(mn.c_str())); - continue; - } - InlineWordCode( pushint ) - { - const auto &cp = abcFile->constant_pool.integers; - const auto &val = cp[bitstream.ReadEncodedU32( )]; - stack.Append( idSWFScriptVar( val ) ); + //ExecWordCode ( pushnan ); + InlineWordCode( pop ) + stack.Pop( 1 ); continue; - } - InlineWordCode ( pushuint ) - { - const auto &cp = abcFile->constant_pool.uIntegers; - const auto &val = cp[bitstream.ReadEncodedU32( )]; - stack.Append( idSWFScriptVar( (int)val ) ); + InlineWordCode( dup ) + stack.Alloc() = idSWFScriptVar( stack.A() ); continue; - } - InlineWordCode ( pushdouble ) - { - const auto &cp = abcFile->constant_pool.doubles; - const auto &val = cp[bitstream.ReadEncodedU32( )]; - stack.Append( idSWFScriptVar( (float)val ) ); + InlineWordCode( swap ) + common->FatalError( "swap not implemented" ); continue; - } - ExecWordCode ( pushscope ); - //ExecWordCode ( pushnamespace ); - //ExecWordCode ( hasnext2 ); - //ExecWordCode ( lix8 ); - //ExecWordCode ( lix16 ); - //ExecWordCode ( li8 ); - //ExecWordCode ( li16 ); - //ExecWordCode ( li32 ); - //ExecWordCode ( lf32 ); - //ExecWordCode ( lf64 ); - //ExecWordCode ( si8 ); - //ExecWordCode ( si8 ); - //ExecWordCode ( si16 ); - //ExecWordCode ( si32 ); - //ExecWordCode ( sf32 ); - //ExecWordCode ( sf64 ); - //ExecWordCode ( newfunction ); - //ExecWordCode ( call ); - //ExecWordCode ( construct ); - //ExecWordCode ( callmethod ); - //ExecWordCode ( callstatic ); - InlineWordCode ( callsuper ) - { - common->FatalError("callsuper not implemented"); - continue; - } - InlineWordCode ( callproperty ) - {//fold this with callpropvoid. - const auto &cp = abcFile->constant_pool; - const auto &mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; - const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; - uint32 arg_count = bitstream.ReadEncodedU32( ); - - idSWFParmList parms( arg_count ); - - for ( int i = 0; i < parms.Num( ); i++ ) { - parms[i] = stack.A( ); - stack.Pop( 1 ); + InlineWordCode( pushstring ) + { + const auto& cp = abcFile->constant_pool.utf8Strings; + const auto& mn = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptString( mn.c_str() ) ); + continue; + } + InlineWordCode( pushint ) + { + const auto& cp = abcFile->constant_pool.integers; + const auto& val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( val ) ); + continue; } - idSWFScriptVar &item = stack.A( ); - if ( item.IsFunction( ) ) - stack.Alloc() = item.GetFunction( )->Call( registers[0].GetObject( ), parms ); - else if ( item.IsObject( ) ) { - auto func = item.GetObject( )->Get( funcName->c_str( ) ); - if ( func.IsFunction( ) ) { - ( ( idSWFScriptFunction_Script * ) func.GetFunction( ) )->SetScope( *GetScope( ) ); - stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); + InlineWordCode( pushuint ) + { + const auto& cp = abcFile->constant_pool.uIntegers; + const auto& val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( ( int )val ) ); + continue; + } + InlineWordCode( pushdouble ) + { + const auto& cp = abcFile->constant_pool.doubles; + const auto& val = cp[bitstream.ReadEncodedU32( )]; + stack.Append( idSWFScriptVar( ( float )val ) ); + continue; + } + ExecWordCode( pushscope ); + //ExecWordCode ( pushnamespace ); + //ExecWordCode ( hasnext2 ); + //ExecWordCode ( lix8 ); + //ExecWordCode ( lix16 ); + //ExecWordCode ( li8 ); + //ExecWordCode ( li16 ); + //ExecWordCode ( li32 ); + //ExecWordCode ( lf32 ); + //ExecWordCode ( lf64 ); + //ExecWordCode ( si8 ); + //ExecWordCode ( si8 ); + //ExecWordCode ( si16 ); + //ExecWordCode ( si32 ); + //ExecWordCode ( sf32 ); + //ExecWordCode ( sf64 ); + //ExecWordCode ( newfunction ); + //ExecWordCode ( call ); + //ExecWordCode ( construct ); + //ExecWordCode ( callmethod ); + //ExecWordCode ( callstatic ); + InlineWordCode( callsuper ) + { + common->FatalError( "callsuper not implemented" ); + continue; + } + InlineWordCode( callproperty ) + { + //fold this with callpropvoid. + const auto& cp = abcFile->constant_pool; + const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + uint32 arg_count = bitstream.ReadEncodedU32( ); + + idSWFParmList parms( arg_count ); + + for( int i = 0; i < parms.Num( ); i++ ) + { + parms[i] = stack.A( ); + stack.Pop( 1 ); + } + idSWFScriptVar& item = stack.A( ); + if( item.IsFunction( ) ) + { + stack.Alloc() = item.GetFunction( )->Call( registers[0].GetObject( ), parms ); } + else if( item.IsObject( ) ) + { + auto func = item.GetObject( )->Get( funcName->c_str( ) ); + if( func.IsFunction( ) ) + { + ( ( idSWFScriptFunction_Script* ) func.GetFunction( ) )->SetScope( *GetScope( ) ); + stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); + } + } + continue; } - continue; - } - InlineWordCode ( returnvoid ) - { - if (scope[scope.Num()-1]) - scope[scope.Num()-1]->Release(); - - scope.SetNum(scope.Num()-1); - continue; - } - //ExecWordCode ( returnvalue ); - InlineWordCode ( constructsuper ) - { - uint32 args = bitstream.ReadEncodedU32( ); - stack.Pop( args ); - continue; - } - InlineWordCode ( constructprop ) - { + InlineWordCode( returnvoid ) + { + if( scope[scope.Num() - 1] ) + { + scope[scope.Num() - 1]->Release(); + } - //no need to call constructors. - const auto &cp = abcFile->constant_pool; - const auto &mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; - const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; - uint32 arg_count = bitstream.ReadEncodedU32( ); - stack.Pop( arg_count ); - continue; + scope.SetNum( scope.Num() - 1 ); + continue; + } + //ExecWordCode ( returnvalue ); + InlineWordCode( constructsuper ) + { + uint32 args = bitstream.ReadEncodedU32( ); + stack.Pop( args ); + continue; + } + InlineWordCode( constructprop ) + { + //no need to call constructors. + const auto& cp = abcFile->constant_pool; + const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + uint32 arg_count = bitstream.ReadEncodedU32( ); + stack.Pop( arg_count ); + continue; - idSWFParmList parms( arg_count ); - for ( int i = 0; i < parms.Num( ); i++ ) { - parms[i] = stack.A( ); - stack.Pop( 1 ); - } + idSWFParmList parms( arg_count ); - idSWFScriptVar prop = stack.A();//scope[0]->Get(propName->c_str()); - if (!prop.IsUndefined() && prop.IsObject()) - { - idSWFScriptObject * newProp = idSWFScriptObject::Alloc(); - stack.Alloc() = newProp; - newProp->DeepCopy(prop.GetObject()); - if ( newProp->HasProperty( "__constructor__" ) ) { - common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); - idSWFScriptVar instanceInit = newProp->Get( "__constructor__" ); - ( ( idSWFScriptFunction_Script * ) instanceInit.GetFunction( ) )->SetScope( *GetScope( ) ); - instanceInit.GetFunction( )->Call( newProp, parms ); + for( int i = 0; i < parms.Num( ); i++ ) + { + parms[i] = stack.A( ); + stack.Pop( 1 ); } - }else - common->Warning("Could not construct %s ",propName->c_str()); - - continue; - } - //ExecWordCode ( callsuperid ); - //ExecWordCode ( callproplex ); - //ExecWordCode ( callinterface ); - //ExecWordCode ( callsupervoid ); - ExecWordCode ( callpropvoid ); - //ExecWordCode ( sxi1 ); - //ExecWordCode ( sxi8 ); - //ExecWordCode ( sxi16 ); - //ExecWordCode ( applytype ); - //ExecWordCode ( DISABLED_pushfloat4 ); - //ExecWordCode ( newobject ); - //ExecWordCode ( newarray ); - //ExecWordCode ( newactivation ); - ExecWordCode ( newclass ); - //ExecWordCode ( getdescendants ); - //ExecWordCode ( newcatch ); - //ExecWordCode ( findpropglobalstrict ); - //ExecWordCode ( findpropglobal ); - ExecWordCode ( findpropstrict ); - //ExecWordCode ( findproperty ); - //ExecWordCode ( finddef ); - ExecWordCode ( getlex ); - InlineWordCode ( setproperty ); - { - const auto &cp = abcFile->constant_pool; - const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; - const auto &n = cp.utf8Strings[mn.nameIndex]; - idSWFScriptVar value = stack.A( ); - stack.Pop( 1 ); - stack.A( ).GetObject( )->Set( n, value ); - continue; - } - InlineWordCode ( getlocal ) - { - stack.Alloc() = registers[bitstream.ReadEncodedU32()]; - continue; - } - //ExecWordCode ( setlocal ); - //ExecWordCode ( getglobalscope ); - ExecWordCode ( getscopeobject ); - InlineWordCode( getproperty ) { + idSWFScriptVar prop = stack.A();//scope[0]->Get(propName->c_str()); + if( !prop.IsUndefined() && prop.IsObject() ) + { + idSWFScriptObject* newProp = idSWFScriptObject::Alloc(); + stack.Alloc() = newProp; + newProp->DeepCopy( prop.GetObject() ); + if( newProp->HasProperty( "__constructor__" ) ) + { + common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); + idSWFScriptVar instanceInit = newProp->Get( "__constructor__" ); + ( ( idSWFScriptFunction_Script* ) instanceInit.GetFunction( ) )->SetScope( *GetScope( ) ); + instanceInit.GetFunction( )->Call( newProp, parms ); + } + } + else + { + common->Warning( "Could not construct %s ", propName->c_str() ); + } - const auto &cp = abcFile->constant_pool; - const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; - const auto &n = cp.utf8Strings[mn.nameIndex]; + continue; + } + //ExecWordCode ( callsuperid ); + //ExecWordCode ( callproplex ); + //ExecWordCode ( callinterface ); + //ExecWordCode ( callsupervoid ); + ExecWordCode( callpropvoid ); + //ExecWordCode ( sxi1 ); + //ExecWordCode ( sxi8 ); + //ExecWordCode ( sxi16 ); + //ExecWordCode ( applytype ); + //ExecWordCode ( DISABLED_pushfloat4 ); + //ExecWordCode ( newobject ); + //ExecWordCode ( newarray ); + //ExecWordCode ( newactivation ); + ExecWordCode( newclass ); + //ExecWordCode ( getdescendants ); + //ExecWordCode ( newcatch ); + //ExecWordCode ( findpropglobalstrict ); + //ExecWordCode ( findpropglobal ); + ExecWordCode( findpropstrict ); + //ExecWordCode ( findproperty ); + //ExecWordCode ( finddef ); + ExecWordCode( getlex ); + InlineWordCode( setproperty ); + { + const auto& cp = abcFile->constant_pool; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& n = cp.utf8Strings[mn.nameIndex]; - if (!stack.A().IsObject()) + idSWFScriptVar value = stack.A( ); + stack.Pop( 1 ); + stack.A( ).GetObject( )->Set( n, value ); + continue; + } + InlineWordCode( getlocal ) { - common->Warning("cant find property %s",n.c_str()); - stack.Pop(1); - stack.Alloc().SetUndefined(); + stack.Alloc() = registers[bitstream.ReadEncodedU32()]; continue; } - auto * obj = stack.A().GetObject(); - stack.Pop(1); + //ExecWordCode ( setlocal ); + //ExecWordCode ( getglobalscope ); + ExecWordCode( getscopeobject ); + InlineWordCode( getproperty ) + { - if ( obj->HasProperty(n.c_str())) - stack.Alloc() = obj->Get(n.c_str()); - else - stack.Alloc().SetUndefined(); + const auto& cp = abcFile->constant_pool; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& n = cp.utf8Strings[mn.nameIndex]; - continue; - } - //ExecWordCode ( getouterscope ); - InlineWordCode ( initproperty ) - { - const auto &cp = abcFile->constant_pool; - const auto &mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; - const auto &n = cp.utf8Strings[mn.nameIndex]; + if( !stack.A().IsObject() ) + { + common->Warning( "cant find property %s", n.c_str() ); + stack.Pop( 1 ); + stack.Alloc().SetUndefined(); + continue; + } + auto* obj = stack.A().GetObject(); + stack.Pop( 1 ); + + if( obj->HasProperty( n.c_str() ) ) + { + stack.Alloc() = obj->Get( n.c_str() ); + } + else + { + stack.Alloc().SetUndefined(); + } - idSWFScriptVar value = stack.A( ); - stack.Pop( 1 ); - stack.A().GetObject()->Set( n,value); - continue; - } - //ExecWordCode ( 0x69 ); - //ExecWordCode ( deleteproperty ); - //ExecWordCode ( 0x6B ); - //ExecWordCode ( getslot ); - //ExecWordCode ( setslot ); - //ExecWordCode ( getglobalslot ); - //ExecWordCode ( setglobalslot ); - //ExecWordCode ( convert_s ); - //ExecWordCode ( esc_xelem ); - //ExecWordCode ( esc_xattr ); - //ExecWordCode ( convert_i ); - //ExecWordCode ( convert_u ); - //ExecWordCode ( convert_d ); - //ExecWordCode ( convert_b ); - //ExecWordCode ( convert_o ); - //ExecWordCode ( checkfilter ); - //ExecWordCode ( DISABLED_convert ); - //ExecWordCode ( DISABLED_unplus ); - //ExecWordCode ( DISABLED_convert ); - //ExecWordCode ( coerce ); - //ExecWordCode ( coerce_b ); - //ExecWordCode ( coerce_a ); - //ExecWordCode ( coerce_i ); - //ExecWordCode ( coerce_d ); - //ExecWordCode ( coerce_s ); - //ExecWordCode ( astype ); - //ExecWordCode ( astypelate ); - //ExecWordCode ( coerce_u ); - //ExecWordCode ( coerce_o ); - //ExecWordCode ( negate ); - InlineWordCode ( increment ) - { - auto &val = stack.A( ); - idSWFScriptVar result; - switch ( val.GetType( ) ) { - case idSWFScriptVar::SWF_VAR_FLOAT: - val.SetFloat( val.ToFloat() + 1.0f ); continue; - case idSWFScriptVar::SWF_VAR_INTEGER: - val.SetInteger(val.ToInteger() + 1); + } + //ExecWordCode ( getouterscope ); + InlineWordCode( initproperty ) + { + const auto& cp = abcFile->constant_pool; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& n = cp.utf8Strings[mn.nameIndex]; + + idSWFScriptVar value = stack.A( ); + stack.Pop( 1 ); + stack.A().GetObject()->Set( n, value ); continue; - default: - common->Warning( " Tried to increment incompatible type %s", val.TypeOf( )); } - continue; - } - //ExecWordCode ( inclocal ); - //ExecWordCode ( decrement ); - //ExecWordCode ( declocal ); - //ExecWordCode ( typeof ); - //ExecWordCode ( not ); - //ExecWordCode ( bitnot ); - InlineWordCode ( add ) - { - auto & lH = stack.B(); - auto & rH = stack.A(); - idSWFScriptVar result; - switch ( lH.GetType( ) ) { - case idSWFScriptVar::SWF_VAR_STRING: - result.SetString( lH.ToString( ) + rH.ToString( ) ); - break; - case idSWFScriptVar::SWF_VAR_FLOAT: - result.SetFloat( lH.ToFloat( ) + rH.ToFloat( ) ); - break; - case idSWFScriptVar::SWF_VAR_INTEGER: - result.SetInteger( lH.ToInteger( ) + rH.ToInteger( ) ); - break; - case idSWFScriptVar::SWF_VAR_FUNCTION: - result.SetString( lH.ToString( ) + rH.ToString( ) ); - break; - default: - common->Warning( " Tried to add incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + //ExecWordCode ( 0x69 ); + //ExecWordCode ( deleteproperty ); + //ExecWordCode ( 0x6B ); + //ExecWordCode ( getslot ); + //ExecWordCode ( setslot ); + //ExecWordCode ( getglobalslot ); + //ExecWordCode ( setglobalslot ); + //ExecWordCode ( convert_s ); + //ExecWordCode ( esc_xelem ); + //ExecWordCode ( esc_xattr ); + //ExecWordCode ( convert_i ); + //ExecWordCode ( convert_u ); + //ExecWordCode ( convert_d ); + //ExecWordCode ( convert_b ); + //ExecWordCode ( convert_o ); + //ExecWordCode ( checkfilter ); + //ExecWordCode ( DISABLED_convert ); + //ExecWordCode ( DISABLED_unplus ); + //ExecWordCode ( DISABLED_convert ); + //ExecWordCode ( coerce ); + //ExecWordCode ( coerce_b ); + //ExecWordCode ( coerce_a ); + //ExecWordCode ( coerce_i ); + //ExecWordCode ( coerce_d ); + //ExecWordCode ( coerce_s ); + //ExecWordCode ( astype ); + //ExecWordCode ( astypelate ); + //ExecWordCode ( coerce_u ); + //ExecWordCode ( coerce_o ); + //ExecWordCode ( negate ); + InlineWordCode( increment ) + { + auto& val = stack.A( ); + idSWFScriptVar result; + switch( val.GetType( ) ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( val.ToFloat() + 1.0f ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger( val.ToInteger() + 1 ); + continue; + default: + common->Warning( " Tried to increment incompatible type %s", val.TypeOf( ) ); + } + continue; } + //ExecWordCode ( inclocal ); + //ExecWordCode ( decrement ); + //ExecWordCode ( declocal ); + //ExecWordCode ( typeof ); + //ExecWordCode ( not ); + //ExecWordCode ( bitnot ); + InlineWordCode( add ) + { + auto& lH = stack.B(); + auto& rH = stack.A(); + idSWFScriptVar result; + switch( lH.GetType( ) ) + { + case idSWFScriptVar::SWF_VAR_STRING: + result.SetString( lH.ToString( ) + rH.ToString( ) ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + result.SetFloat( lH.ToFloat( ) + rH.ToFloat( ) ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + result.SetInteger( lH.ToInteger( ) + rH.ToInteger( ) ); + break; + case idSWFScriptVar::SWF_VAR_FUNCTION: + result.SetString( lH.ToString( ) + rH.ToString( ) ); + break; + default: + common->Warning( " Tried to add incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + } - stack.Pop(2); - stack.Alloc() = result; - continue; - } - //ExecWordCode ( subtract ); - //ExecWordCode ( multiply ); - //ExecWordCode ( divide ); - //ExecWordCode ( modulo ); - //ExecWordCode ( lshift ); - //ExecWordCode ( rshift ); - //ExecWordCode ( urshift ); - //ExecWordCode ( bitand ); - //ExecWordCode ( bitor ); - //ExecWordCode ( bitxor ); - //ExecWordCode ( equals ); - //ExecWordCode ( strictequals ); - //ExecWordCode ( lessthan ); - //ExecWordCode ( lessequals ); - //ExecWordCode ( greaterthan ); - //ExecWordCode ( greaterequals ); - //ExecWordCode ( instanceof ); - //ExecWordCode ( istype ); - //ExecWordCode ( istypelate ); - //ExecWordCode ( in ); - //ExecWordCode ( increment_i ); - //ExecWordCode ( decrement_i ); - //ExecWordCode ( inclocal_i ); - //ExecWordCode ( declocal_i ); - //ExecWordCode ( negate_i ); - //ExecWordCode ( add_i ); - //ExecWordCode ( subtract_i ); - //ExecWordCode ( multiply_i ); - InlineWordCode ( getlocal0 ) { stack.Alloc() = registers[0]; continue;} - InlineWordCode ( getlocal1 ) { stack.Alloc() = registers[1]; continue;} - InlineWordCode ( getlocal2 ) { stack.Alloc() = registers[2]; continue;} - InlineWordCode ( getlocal3 ) { stack.Alloc() = registers[3]; continue;} - InlineWordCode ( setlocal0 ) { registers[0] = stack.A(); continue;} - InlineWordCode ( setlocal1 ) { registers[1] = stack.A(); continue;} - InlineWordCode ( setlocal2 ) { registers[2] = stack.A(); continue;} - InlineWordCode ( setlocal3 ) { registers[3] = stack.A(); continue;} - InlineWordCode ( debug ) - { - uint8 type = bitstream.ReadU8(); - uint32 index = bitstream.ReadEncodedU32(); - uint8 reg = bitstream.ReadU8(); - uint32 extra = bitstream.ReadEncodedU32(); - continue; - } - InlineWordCode ( debugline ) - InlineWordCode ( debugfile ) + stack.Pop( 2 ); + stack.Alloc() = result; + continue; + } + //ExecWordCode ( subtract ); + //ExecWordCode ( multiply ); + //ExecWordCode ( divide ); + //ExecWordCode ( modulo ); + //ExecWordCode ( lshift ); + //ExecWordCode ( rshift ); + //ExecWordCode ( urshift ); + //ExecWordCode ( bitand ); + //ExecWordCode ( bitor ); + //ExecWordCode ( bitxor ); + //ExecWordCode ( equals ); + //ExecWordCode ( strictequals ); + //ExecWordCode ( lessthan ); + //ExecWordCode ( lessequals ); + //ExecWordCode ( greaterthan ); + //ExecWordCode ( greaterequals ); + //ExecWordCode ( instanceof ); + //ExecWordCode ( istype ); + //ExecWordCode ( istypelate ); + //ExecWordCode ( in ); + //ExecWordCode ( increment_i ); + //ExecWordCode ( decrement_i ); + //ExecWordCode ( inclocal_i ); + //ExecWordCode ( declocal_i ); + //ExecWordCode ( negate_i ); + //ExecWordCode ( add_i ); + //ExecWordCode ( subtract_i ); + //ExecWordCode ( multiply_i ); + InlineWordCode( getlocal0 ) + { + stack.Alloc() = registers[0]; + continue; + } + InlineWordCode( getlocal1 ) + { + stack.Alloc() = registers[1]; + continue; + } + InlineWordCode( getlocal2 ) + { + stack.Alloc() = registers[2]; + continue; + } + InlineWordCode( getlocal3 ) + { + stack.Alloc() = registers[3]; + continue; + } + InlineWordCode( setlocal0 ) + { + registers[0] = stack.A(); + continue; + } + InlineWordCode( setlocal1 ) + { + registers[1] = stack.A(); + continue; + } + InlineWordCode( setlocal2 ) + { + registers[2] = stack.A(); + continue; + } + InlineWordCode( setlocal3 ) + { + registers[3] = stack.A(); + continue; + } + InlineWordCode( debug ) + { + uint8 type = bitstream.ReadU8(); + uint32 index = bitstream.ReadEncodedU32(); + uint8 reg = bitstream.ReadU8(); + uint32 extra = bitstream.ReadEncodedU32(); + continue; + } + InlineWordCode( debugline ) + InlineWordCode( debugfile ) uint32 nr = bitstream.ReadEncodedU32(); - continue; - //ExecWordCode ( bkptline ); - //ExecWordCode ( timestamp ); - //ExecWordCode ( restargc ); - //ExecWordCode ( restarg ); - //ExecWordCode ( codes ); + continue; + //ExecWordCode ( bkptline ); + //ExecWordCode ( timestamp ); + //ExecWordCode ( restargc ); + //ExecWordCode ( restarg ); + //ExecWordCode ( codes ); } } diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 79634d84bf..71dabec6cd 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -37,7 +37,7 @@ using namespace rapidjson;//bleh #pragma warning(disable: 4355) // 'this' : used in base member initializer list -idCVar swf_fatalVersionMismatch("swf_fatalVersionMismatch", "0", CVAR_BOOL, "Version number mismatch results in fatal error"); +idCVar swf_fatalVersionMismatch( "swf_fatalVersionMismatch", "0", CVAR_BOOL, "Version number mismatch results in fatal error" ); #define BSWF_VERSION 16 // bumped to 16 for storing atlas image dimensions for unbuffered loads #define BSWF_MAGIC ( ( 'B' << 24 ) | ( 'S' << 16 ) | ( 'W' << 8 ) | BSWF_VERSION ) @@ -71,9 +71,10 @@ bool idSWF::LoadSWF( const char* fullpath ) return false; } - if ( header.version >= 9 ) { + if( header.version >= 9 ) + { idLib::Warning( "Unsupported version %d", header.version ); - if (swf_fatalVersionMismatch.GetBool() ) + if( swf_fatalVersionMismatch.GetBool() ) { delete rawfile; return false; diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 045b430868..87fbe02ef2 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -35,7 +35,7 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_loadBinary( "swf_loadBinary", "1", CVAR_INTEGER, "used to set whether to load binary swf from generated" ); -idCVar swf_printAbcObjects("swf_printAbcObjects", "1", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag"); +idCVar swf_printAbcObjects( "swf_printAbcObjects", "1", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag" ); int idSWF::mouseX = -1; int idSWF::mouseY = -1; @@ -45,37 +45,41 @@ extern idCVar in_useJoystick; idSWFScriptObject_EventDispatcherPrototype eventDispatcherScriptObjectPrototype; -void idSWF::CreateAbcObjects( idSWFScriptObject *globals ) +void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) { //2 passes. //1. Create all classes int idx = 0; - for (auto & classInfo : abcFile.classes ) + for( auto& classInfo : abcFile.classes ) { - swfInstance_info & instanceInfo = abcFile.instances[idx]; + swfInstance_info& instanceInfo = abcFile.instances[idx]; - idSWFScriptObject * tmp = idSWFScriptObject::Alloc(); + idSWFScriptObject* tmp = idSWFScriptObject::Alloc(); idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; //if these are namespace sets, concat all? idStr fullClassName = *abcFile.constant_pool.namespaceNames[instanceInfo.name->index] + "." + abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; idStr& superName = abcFile.constant_pool.utf8Strings[instanceInfo.super_name->nameIndex]; //lookup prototype - if (globals->HasValidProperty(superName)) - tmp->SetPrototype(globals->GetObject(superName)->GetPrototype()); + if( globals->HasValidProperty( superName ) ) + { + tmp->SetPrototype( globals->GetObject( superName )->GetPrototype() ); + } else - common->Warning(" prototype %s not found for %s",className.c_str(),superName.c_str()); - - idSWFScriptFunction_Script * init = idSWFScriptFunction_Script::Alloc(); + { + common->Warning( " prototype %s not found for %s", className.c_str(), superName.c_str() ); + } + + idSWFScriptFunction_Script* init = idSWFScriptFunction_Script::Alloc(); init->SetData( classInfo.cinit ); tmp->Set( "__initializer__", idSWFScriptVar( init ) ); - init->SetAbcFile(&abcFile); - idSWFScriptFunction_Script *constr = idSWFScriptFunction_Script::Alloc( ); + init->SetAbcFile( &abcFile ); + idSWFScriptFunction_Script* constr = idSWFScriptFunction_Script::Alloc( ); constr->SetData( instanceInfo.iinit ); tmp->Set( "__constructor__", idSWFScriptVar( constr ) ); - constr->SetAbcFile(&abcFile); - globals->Set(className,tmp); - globals->Set(fullClassName,tmp); + constr->SetAbcFile( &abcFile ); + globals->Set( className, tmp ); + globals->Set( fullClassName, tmp ); idx++; //check release init->Release(); @@ -84,30 +88,33 @@ void idSWF::CreateAbcObjects( idSWFScriptObject *globals ) idx = 0; //2, create all traits - for ( auto &classInfo : abcFile.classes ) { - swfInstance_info &instanceInfo = abcFile.instances[idx]; - - idStr &className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; - idSWFScriptObject *tmp = globals->GetObject( className ); - auto * target = idSWFScriptObject::Alloc( ); - auto *var = tmp->GetVariable( "[" + className + "]", true ); - - for ( swfTraits_info &trait : instanceInfo.traits ) { - target->Set( abcFile.constant_pool.utf8Strings[trait.name->nameIndex], - abcFile.GetTrait( trait, globals )->value); + for( auto& classInfo : abcFile.classes ) + { + swfInstance_info& instanceInfo = abcFile.instances[idx]; + + idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; + idSWFScriptObject* tmp = globals->GetObject( className ); + auto* target = idSWFScriptObject::Alloc( ); + auto* var = tmp->GetVariable( "[" + className + "]", true ); + + for( swfTraits_info& trait : instanceInfo.traits ) + { + target->Set( abcFile.constant_pool.utf8Strings[trait.name->nameIndex], + abcFile.GetTrait( trait, globals )->value ); } - var->value.SetObject(target); + var->value.SetObject( target ); target->Release(); - for ( swfTraits_info &trait : classInfo.traits ) { + for( swfTraits_info& trait : classInfo.traits ) + { tmp->Set( abcFile.constant_pool.utf8Strings[trait.name->nameIndex], - abcFile.GetTrait( trait, globals )->value - ); + abcFile.GetTrait( trait, globals )->value + ); } - if (swf_printAbcObjects.GetBool()) + if( swf_printAbcObjects.GetBool() ) { - tmp->PrintToConsole(className.c_str()); - target->PrintToConsole("[" + className + "]"); + tmp->PrintToConsole( className.c_str() ); + target->PrintToConsole( "[" + className + "]" ); } idx++; } @@ -167,7 +174,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, isActive = false; inhibitControl = false; - useInhibtControl = true; + useInhibtControl = false; crop = false; blackbars = false; @@ -228,8 +235,10 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, } else if( LoadSWF( filename ) ) { - if (!abcFile.class_count) + if( !abcFile.class_count ) + { WriteBinary( binaryFileName ); + } } } } @@ -420,25 +429,27 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals = idSWFScriptObject::Alloc(); globals->Set( "_global", globals ); - auto *accessibilityPropertiesObj = idSWFScriptObject::Alloc( ); + auto* accessibilityPropertiesObj = idSWFScriptObject::Alloc( ); //accessibilityPropertiesObj->Set( "", idSWFScriptObject::Alloc( ) ); - - auto *dispatcherObj = idSWFScriptObject::Alloc( ); + + auto* dispatcherObj = idSWFScriptObject::Alloc( ); dispatcherObj->SetPrototype( &eventDispatcherScriptObjectPrototype ); extern idSWFScriptObject_SpriteInstancePrototype spriteInstanceScriptObjectPrototype; - auto *movieclipObj = idSWFScriptObject::Alloc( ); + auto* movieclipObj = idSWFScriptObject::Alloc( ); movieclipObj->SetPrototype( &spriteInstanceScriptObjectPrototype ); - if (spriteInstanceScriptObjectPrototype.GetPrototype() == NULL) + if( spriteInstanceScriptObjectPrototype.GetPrototype() == NULL ) + { spriteInstanceScriptObjectPrototype.SetPrototype( &eventDispatcherScriptObjectPrototype ); + } globals->Set( "Object", &scriptFunction_Object ); - globals->Set( "EventDispatcher", dispatcherObj ); + globals->Set( "EventDispatcher", dispatcherObj ); globals->Set( "DisplayObject", idSWFScriptObject::Alloc( ) ); globals->Set( "InteractiveObject", idSWFScriptObject::Alloc( ) ); globals->Set( "AccessibilityProperties", accessibilityPropertiesObj ); - globals->Set( "Dictionary", idSWFScriptObject::Alloc()); + globals->Set( "Dictionary", idSWFScriptObject::Alloc() ); globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); globals->Set( "Sprite", idSWFScriptObject::Alloc( ) ); globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); @@ -451,17 +462,21 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, mainspriteInstance->abcFile = &abcFile; mainspriteInstance->scriptObject = idSWFScriptObject::Alloc( ); //stage class. - - for ( auto &symbol : symbolClasses.symbols ) { - if ( !symbol.tag ) { + + for( auto& symbol : symbolClasses.symbols ) + { + if( !symbol.tag ) + { mainspriteInstance->name = symbol.name; idStr objName; - mainspriteInstance->name.ExtractFileExtension(objName); + mainspriteInstance->name.ExtractFileExtension( objName ); - auto *super = globals->Get( symbol.name ).GetObject( ); - auto dcopy = super->Get("[" + objName + "]"); - if (dcopy.IsObject()) + auto* super = globals->Get( symbol.name ).GetObject( ); + auto dcopy = super->Get( "[" + objName + "]" ); + if( dcopy.IsObject() ) + { mainspriteInstance->scriptObject->DeepCopy( dcopy.GetObject( ) ); + } mainspriteInstance->scriptObject->SetPrototype( super ); mainspriteInstance->scriptObject->Set( "root", mainspriteInstance->scriptObject ); @@ -501,14 +516,14 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "floor", scriptFunction_floor.Bind( this ) ); globals->Set( "ceil", scriptFunction_ceil.Bind( this ) ); globals->Set( "toUpper", scriptFunction_toUpper.Bind( this ) ); - globals->Set( "trace", scriptFunction_trace.Bind(this)); + globals->Set( "trace", scriptFunction_trace.Bind( this ) ); globals->SetNative( "platform", swfScriptVar_platform.Bind( &scriptFunction_getPlatform ) ); globals->SetNative( "blackbars", swfScriptVar_blackbars.Bind( this ) ); globals->SetNative( "cropToHeight", swfScriptVar_crop.Bind( this ) ); globals->SetNative( "cropToFit", swfScriptVar_crop.Bind( this ) ); globals->SetNative( "crop", swfScriptVar_crop.Bind( this ) ); - + // Do this to touch any external references (like sounds) // But disable script warnings because many globals won't have been created yet extern idCVar swf_debug; @@ -518,7 +533,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, //The original impl does an initial run when contructing the stage. //This is not possible with swf's that have the tag DoABC / run abc-bytecode - if (!skipInitOnContruct) + if( !skipInitOnContruct ) { mainspriteInstance->Run(); mainspriteInstance->RunActions(); @@ -1111,9 +1126,10 @@ void idSWF::idSWFScriptNativeVar_crop::Set( idSWFScriptObject* object, const idS pThis->crop = value.ToBool(); } -idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call(idSWFScriptObject* thisObject, const idSWFParmList& parms) { - common->Printf("[%s] %s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", - parms[0].ToString().c_str()); +idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) +{ + common->Printf("^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", + parms[0].ToString().c_str() ); return idSWFScriptVar(); } diff --git a/neo/swf/SWF_PlaceObject.cpp b/neo/swf/SWF_PlaceObject.cpp index 073867328e..b2d8e1e1bf 100644 --- a/neo/swf/SWF_PlaceObject.cpp +++ b/neo/swf/SWF_PlaceObject.cpp @@ -45,12 +45,15 @@ void idSWFSpriteInstance::PlaceObject2( idSWFBitStream& bitstream ) uint64 flags = bitstream.ReadU8(); int depth = bitstream.ReadU16(); - if ( ( flags & PlaceFlagHasClassName ) != 0 ) + //if( ( flags & PlaceFlagHasClassName ) != 0 ) + //{ // idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); - if ( ( ( ( flags & PlaceFlagHasImage ) != 0 ) && ( ( flags & PlaceFlagHasCharacter ) != 0 ) ) ) { - // idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString( ) ); - } + //if( ( ( ( flags & PlaceFlagHasImage ) != 0 ) && ( ( flags & PlaceFlagHasCharacter ) != 0 ) ) ) + //{ + // idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString( ) ); + //} + //} int characterID = -1; if( ( flags & PlaceFlagHasCharacter ) != 0 ) @@ -145,7 +148,7 @@ void idSWFSpriteInstance::PlaceObject2( idSWFBitStream& bitstream ) idSWFSpriteInstance::PlaceObject3 ======================== */ -void idSWFSpriteInstance::PlaceObject3( idSWFBitStream& bitstream ) +void idSWFSpriteInstance::PlaceObject3(idSWFBitStream& bitstream) { c_PlaceObject3++; @@ -153,13 +156,15 @@ void idSWFSpriteInstance::PlaceObject3( idSWFBitStream& bitstream ) uint64 flags2 = bitstream.ReadU8(); uint16 depth = bitstream.ReadU16(); - if ( ( flags2 & PlaceFlagHasClassName ) != 0 || ( flags1 & PlaceFlagHasClassName ) ) + //if( ( flags2 & PlaceFlagHasClassName ) != 0 || ( flags1 & PlaceFlagHasClassName ) ) + //{ //idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); - - if ( ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) { + //if( ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) + //{ //idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString() ); - } - + //} + //} + int characterID = -1; if( ( flags1 & PlaceFlagHasCharacter ) != 0 ) { diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index fe5ad60824..c530423ad2 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -138,24 +138,24 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, { stack[ parms.Num() - i - 1 ] = parms[i]; // Unfortunately at this point we don't have the function name anymore, so our warning messages aren't very detailed - if (i < parameters.Num()) + if( i < parameters.Num() ) { - if (parameters[i].reg > 0 && parameters[i].reg < registers.Num()) + if( parameters[i].reg > 0 && parameters[i].reg < registers.Num() ) { registers[parameters[i].reg] = parms[i]; } - locals->Set(parameters[i].name, parms[i]); + locals->Set( parameters[i].name, parms[i] ); } } // Set any additional parameters to undefined - for (int i = parms.Num(); i < parameters.Num(); i++) + for( int i = parms.Num(); i < parameters.Num(); i++ ) { - if (parameters[i].reg > 0 && parameters[i].reg < registers.Num()) + if( parameters[i].reg > 0 && parameters[i].reg < registers.Num() ) { registers[parameters[i].reg].SetUndefined(); } - locals->Set(parameters[i].name, idSWFScriptVar()); + locals->Set( parameters[i].name, idSWFScriptVar() ); } stack.A().SetInteger( parms.Num() ); @@ -249,17 +249,21 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, scope.Append( locals ); locals->AddRef(); idSWFScriptVar retVal; - if ( methodInfo != nullptr ) { + if( methodInfo != nullptr ) + { assert( methodInfo->body ); - auto *body = methodInfo->body; + auto* body = methodInfo->body; registers[0].SetObject( thisObject ); idSWFBitStream abcStream( methodInfo->body->code.Ptr( ), methodInfo->body->codeLength, false ); retVal = RunAbc( thisObject, stack, abcStream ); locals->Release( ); locals = NULL; return retVal; - }else + } + else + { retVal = Run( thisObject, stack, bitstream ); + } assert( scope.Num() == scopeSize + 1 ); for( int i = scopeSize; i < scope.Num(); i++ ) diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index edd9e4d655..b2012976e0 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -186,7 +186,7 @@ idSWFScriptFunction_Script is a script function that's implemented in action scr class idSWFScriptFunction_Script : public idSWFScriptFunction { public: - idSWFScriptFunction_Script() : refCount( 1 ), flags( 0 ), data( NULL ), length( 0 ), prototype( NULL ), defaultSprite( NULL ), methodInfo(NULL), abcFile(NULL) + idSWFScriptFunction_Script() : refCount( 1 ), flags( 0 ), data( NULL ), length( 0 ), prototype( NULL ), defaultSprite( NULL ), methodInfo( NULL ), abcFile( NULL ) { registers.SetNum( 4 ); } @@ -218,11 +218,23 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction data = _data; length = _length; } - void SetData( swfMethod_info * _method) { methodInfo = _method; } - void SetAbcFile ( SWF_AbcFile * _file ) { abcFile = _file; } - swfMethod_info * GetMethodInfo( ) { return methodInfo;} + void SetData( swfMethod_info* _method ) + { + methodInfo = _method; + } + void SetAbcFile( SWF_AbcFile* _file ) + { + abcFile = _file; + } + swfMethod_info* GetMethodInfo( ) + { + return methodInfo; + } void SetScope( idList& scope ); - idList * GetScope() { return &scope; } + idList* GetScope() + { + return &scope; + } void SetConstants( const idSWFConstantPool& _constants ) { constants.Copy( _constants ); @@ -265,16 +277,16 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction ////////////////////////////////////////////////////////////////////////// //////////////////////ABC Wordcode Interpretation///////////////////////// ////////////////////////////////////////////////////////////////////////// - void findpropstrict( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void getlex( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void getscopeobject( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void pushscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void popscope( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void getlocal0( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void newclass( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); - void callpropvoid( SWF_AbcFile *file, idSWFStack &stack, idSWFBitStream &bitstream ); + void findpropstrict( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void getscopeobject( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void pushscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void popscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void getlocal0( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void newclass( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); + void callpropvoid( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); ////////////////////////////////////////////////////////////////////////// - + idSWFScriptVar Run( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream ); struct ActionBlock @@ -297,8 +309,8 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction // RB end - idSWFScriptVar RunAbc( idSWFScriptObject * thisObject, idSWFStack & stack, idSWFBitStream & bitstream ); - SWF_AbcFile *abcFile; + idSWFScriptVar RunAbc( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream ); + SWF_AbcFile* abcFile; private: std::atomic refCount; @@ -321,7 +333,7 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction }; idList< parmInfo_t > parameters; - swfMethod_info *methodInfo; + swfMethod_info* methodInfo; }; #endif // !__SWF_SCRIPTFUNCTION_H__ diff --git a/neo/swf/SWF_ScriptObject.cpp b/neo/swf/SWF_ScriptObject.cpp index c2e44bae78..b310766b79 100644 --- a/neo/swf/SWF_ScriptObject.cpp +++ b/neo/swf/SWF_ScriptObject.cpp @@ -59,10 +59,14 @@ idSWFScriptObject::swfNamedVar_t& idSWFScriptObject::swfNamedVar_t::operator=( c return *this; } -void idSWFScriptObject::DeepCopy( idSWFScriptObject *_object ) { - if ( _object != NULL ) { - for ( int i = 0; i < _object->NumVariables( ); i++ ) +void idSWFScriptObject::DeepCopy( idSWFScriptObject* _object ) +{ + if( _object != NULL ) + { + for( int i = 0; i < _object->NumVariables( ); i++ ) + { Set( _object->EnumVariable( i ), _object->Get( _object->EnumVariable( i ) ) ); + } } } @@ -668,15 +672,21 @@ idSWFTextInstance* idSWFScriptObject::GetNestedText( const char* arg1, const cha idSWFScriptObject::PrintToConsole ======================== */ -void idSWFScriptObject::PrintToConsole(const char * name) const { +void idSWFScriptObject::PrintToConsole( const char* name ) const +{ static int recursionCount = 0; common->Printf( "------------------------------------------------------------\n" ); - if ( variables.Num() > 0 ) { - if ( name ) - idLib::Printf( "[%s] %d subelements:\n",name, variables.Num() ); + if( variables.Num() > 0 ) + { + if( name ) + { + idLib::Printf( "[%s] %d subelements:\n", name, variables.Num() ); + } else + { idLib::Printf( "%d subelements:\n", variables.Num() ); + } int maxVarLength = 0; for( int i = 0; i < variables.Num(); ++i ) @@ -700,13 +710,17 @@ void idSWFScriptObject::PrintToConsole(const char * name) const { idLib::Printf( fmt, nv.name.c_str(), nv.value.TypeOf(), nv.value.ToString().c_str() ); } - } - else + } + else { - if ( name ) + if( name ) + { idLib::Printf( "[%s] No subelements:\n", name ); + } else + { idLib::Printf( "No subelements\n" ); - + } + } } diff --git a/neo/swf/SWF_ScriptObject.h b/neo/swf/SWF_ScriptObject.h index a41f92e99f..e18b7c571e 100644 --- a/neo/swf/SWF_ScriptObject.h +++ b/neo/swf/SWF_ScriptObject.h @@ -140,7 +140,7 @@ class idSWFScriptObject return ( objectType == SWF_OBJECT_TEXT ) ? data.text : NULL; } - void DeepCopy( idSWFScriptObject *_object ); + void DeepCopy( idSWFScriptObject* _object ); // Also accessible via __proto__ property idSWFScriptObject* GetPrototype() { @@ -182,7 +182,7 @@ class idSWFScriptObject idSWFSpriteInstance* GetNestedSprite( const char* arg1, const char* arg2 = NULL, const char* arg3 = NULL, const char* arg4 = NULL, const char* arg5 = NULL, const char* arg6 = NULL ); idSWFTextInstance* GetNestedText( const char* arg1, const char* arg2 = NULL, const char* arg3 = NULL, const char* arg4 = NULL, const char* arg5 = NULL, const char* arg6 = NULL ); - void PrintToConsole(const char * name = nullptr) const; + void PrintToConsole( const char* name = nullptr ) const; struct swfNamedVar_t { @@ -198,16 +198,17 @@ class idSWFScriptObject int flags; }; - swfNamedVar_t * GetVariable( int index, bool create ); - swfNamedVar_t * GetVariable( const char * name, bool create ); + swfNamedVar_t* GetVariable( int index, bool create ); + swfNamedVar_t* GetVariable( const char* name, bool create ); private: std::atomic refCount; bool noAutoDelete; - enum swfNamedVarFlags_t { + enum swfNamedVarFlags_t + { SWF_VAR_FLAG_NONE = 0, - SWF_VAR_FLAG_READONLY = BIT(1), - SWF_VAR_FLAG_DONTENUM = BIT(2) + SWF_VAR_FLAG_READONLY = BIT( 1 ), + SWF_VAR_FLAG_DONTENUM = BIT( 2 ) }; idList< swfNamedVar_t, TAG_SWF > variables; diff --git a/neo/swf/SWF_ScriptVar.h b/neo/swf/SWF_ScriptVar.h index ae2f7ab3ad..f578fdbbf2 100644 --- a/neo/swf/SWF_ScriptVar.h +++ b/neo/swf/SWF_ScriptVar.h @@ -69,18 +69,43 @@ they can contain raw data (int, float), strings, functions, or objects ======================== */ struct swfTraits_info; -class idSWFScriptVar { +class idSWFScriptVar +{ public: - idSWFScriptVar() : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { } - idSWFScriptVar( const idSWFScriptVar & other ); - idSWFScriptVar( idSWFScriptObject * o ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetObject( o ); } - idSWFScriptVar( idStrId s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( s ); } - idSWFScriptVar( const idStr & s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( s ); } - idSWFScriptVar( const char * s ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetString( idStr( s ) ); } - idSWFScriptVar( float f ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetFloat( f ); } - idSWFScriptVar( bool b ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetBool( b ); } - idSWFScriptVar( int32 i ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetInteger( i ); } - idSWFScriptVar( idSWFScriptFunction * nf ) : traitsInfo( NULL ),type( SWF_VAR_UNDEF ) { SetFunction( nf ); } + idSWFScriptVar() : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) { } + idSWFScriptVar( const idSWFScriptVar& other ); + idSWFScriptVar( idSWFScriptObject* o ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetObject( o ); + } + idSWFScriptVar( idStrId s ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetString( s ); + } + idSWFScriptVar( const idStr& s ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetString( s ); + } + idSWFScriptVar( const char* s ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetString( idStr( s ) ); + } + idSWFScriptVar( float f ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetFloat( f ); + } + idSWFScriptVar( bool b ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetBool( b ); + } + idSWFScriptVar( int32 i ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetInteger( i ); + } + idSWFScriptVar( idSWFScriptFunction* nf ) : traitsInfo( NULL ), type( SWF_VAR_UNDEF ) + { + SetFunction( nf ); + } ~idSWFScriptVar(); idSWFScriptVar& operator=( const idSWFScriptVar& other ); @@ -248,7 +273,7 @@ class idSWFScriptVar { return type; } - const swfTraits_info * traitsInfo; + const swfTraits_info* traitsInfo; private: void Free(); swfScriptVarType type; diff --git a/neo/swf/SWF_ShapeParser.cpp b/neo/swf/SWF_ShapeParser.cpp index eac85c6edb..96f1177c71 100644 --- a/neo/swf/SWF_ShapeParser.cpp +++ b/neo/swf/SWF_ShapeParser.cpp @@ -31,19 +31,21 @@ If you have questions concerning this license or the applicable additional terms #pragma warning( disable: 4189 ) // local variable is initialized but not referenced -void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine &ld,swfSPMorphEdge_t & edge,bool end) +void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool end ) { - //figure out what the orientation of the cap is. + //figure out what the orientation of the cap is. idVec2 up = ( verts[edge.start.v0] - verts[edge.start.v1] ); idVec2 down = ( verts[edge.end.v1] - verts[edge.end.v0] ); idVec2 cross = idVec2( down.y, -down.x ); idVec2 crossUp = idVec2( up.y, -up.x ); - + uint8 vertIndex; - if (end ) + if( end ) + { vertIndex = edge.start.v1; + } else { vertIndex = edge.start.v0; @@ -55,7 +57,7 @@ void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFSh float x, z; swfMatrix_t matrix; float s, c; - idVec2 xup(1.0f, 0.0f ); + idVec2 xup( 1.0f, 0.0f ); float angle = idMath::ATan( xup.y - cross.y, xup.x - cross.x ) + idMath::PI; idMath::SinCos( angle, s, c ); @@ -65,23 +67,32 @@ void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFSh matrix.xy = -s * scale; matrix.yy = c * scale; int A, B; - for ( float w = 0.0; w <= 180 ; w += 10 ) { + for( float w = 0.0; w <= 180 ; w += 10 ) + { - if ( !w ) + if( !w ) + { idMath::SinCos( DEG2RAD( w ), z, x ); + } else + { idMath::SinCos( DEG2RAD( w ), z, x ); + } ld.indices.Append( capCenterIdx ); A = ld.startVerts.AddUnique( matrix.Transform( idVec2( x, z ) ) + ld.startVerts[capCenterIdx] ); - if ( w > 10 ) { + if( w > 10 ) + { ld.indices.Append( B ); ld.indices.Append( A ); ld.indices.Append( capCenterIdx ); - - }else if (w + 10 <= 180) - w+=10; + + } + else if( w + 10 <= 180 ) + { + w += 10; + } ld.indices.Append( A ); @@ -121,10 +132,11 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int //generate triangle mesh shape.lineDraws.SetNum( lineDraws.Num() ); int last = 0; - for ( int i = 0; i < lineDraws.Num(); i++ ) { + for( int i = 0; i < lineDraws.Num(); i++ ) + { - idSWFShapeDrawLine & ld = shape.lineDraws[i]; - swfSPDrawLine_t & spld = lineDraws[i]; + idSWFShapeDrawLine& ld = shape.lineDraws[i]; + swfSPDrawLine_t& spld = lineDraws[i]; ld.style = spld.style; float startWidth = ld.style.startWidth; float endWidth = ld.style.endWidth; @@ -135,24 +147,24 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int for( int e = 0; e < spld.edges.Num(); e++ ) { //startcap - if(ld.style.startCapStyle == 0 && ld.style.startWidth > 60 && spld.edges.Num()) + if( ld.style.startCapStyle == 0 && ld.style.startWidth > 60 && spld.edges.Num() ) { - MakeCap(spld, ld, spld.edges[e], false); + MakeCap( spld, ld, spld.edges[e], false ); } //joint. - idVec2 up = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ); - idVec2 down = ( verts[ spld.edges[e].start.v1 ] - verts[ spld.edges[e].start.v0 ] ); - idVec2 cross = idVec2(down.y,-down.x); - idVec2 crossUp = idVec2(up.y,-up.x); - idVec2 offSetA = crossUp * ((1.0f / down.Length()) * ld.style.startWidth / 20); - idVec2 offSetB = cross * ((1.0f / down.Length()) * ld.style.startWidth / 40); - - int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetB); - int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetA + offSetB); + idVec2 up = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ); + idVec2 down = ( verts[ spld.edges[e].start.v1 ] - verts[ spld.edges[e].start.v0 ] ); + idVec2 cross = idVec2( down.y, -down.x ); + idVec2 crossUp = idVec2( up.y, -up.x ); + idVec2 offSetA = crossUp * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 20 ); + idVec2 offSetB = cross * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 40 ); + + int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetB ); + int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetA + offSetB ); ld.indices.Append( v0 ); - if (spld.edges[e].start.cp == 0xFFFF) + if( spld.edges[e].start.cp == 0xFFFF ) { - ld.indices.Append(v0x); + ld.indices.Append( v0x ); } int last = v0x; // Rather then tesselating curves at run time, we do them once here by inserting a vert every 10 units @@ -165,9 +177,9 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int int numPoints = 1 + idMath::Ftoi( Max( length1, length2 ) / 10.0f ); int lastV1; int lastV2; - for ( int ti = 0; ti < numPoints; ti++ ) + for( int ti = 0; ti < numPoints; ti++ ) { - float t0 = ( ti + 1 ) / ( (float) numPoints + 1.0f ); + float t0 = ( ti + 1 ) / ( ( float ) numPoints + 1.0f ); float t1 = ( 1.0f - t0 ); float c1 = t1 * t1; float c2 = t0 * t1 * 2.0f; @@ -177,41 +189,41 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int p1 += c2 * verts[ spld.edges[e].start.cp ]; p1 += c3 * verts[ spld.edges[e].start.v1 ]; - t0 = ( ti + 1 + 1 ) / ( ( float ) numPoints + 1.0f ); - t1 = ( 1.0f - t0 ); - c1 = t1 * t1; - c2 = t0 * t1 * 2.0f; - c3 = t0 * t0; + t0 = ( ti + 1 + 1 ) / ( ( float ) numPoints + 1.0f ); + t1 = ( 1.0f - t0 ); + c1 = t1 * t1; + c2 = t0 * t1 * 2.0f; + c3 = t0 * t0; idVec2 p2 = c1 * verts[spld.edges[e].start.v0]; - p2 += c2 * verts[spld.edges[e].start.cp]; - p2 += c3 * verts[spld.edges[e].start.v1]; + p2 += c2 * verts[spld.edges[e].start.cp]; + p2 += c3 * verts[spld.edges[e].start.v1]; - idVec2 iup = p1 - p2; - idVec2 idown = p2 - p1; - idVec2 icross = idVec2( idown.y, -idown.x ); - idVec2 icrossUp = idVec2( iup.y, -iup.x ); - idVec2 ioffSetA = icrossUp * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 20 ); - idVec2 ioffSetB = icross * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 40 ); + idVec2 iup = p1 - p2; + idVec2 idown = p2 - p1; + idVec2 icross = idVec2( idown.y, -idown.x ); + idVec2 icrossUp = idVec2( iup.y, -iup.x ); + idVec2 ioffSetA = icrossUp * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 20 ); + idVec2 ioffSetB = icross * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 40 ); int v1 = ld.startVerts.AddUnique( p1 + ioffSetB ) ; int v2 = ld.startVerts.AddUnique( p1 + ioffSetA + ioffSetB ) ; - if (ti > 0 ) + if( ti > 0 ) { ld.indices.Append( v2 ); ld.indices.Append( lastV1 ); } - if (ti == 0) + if( ti == 0 ) { - ld.indices.Append(v2); + ld.indices.Append( v2 ); } ld.indices.Append( v1 ); ld.indices.Append( v2 ); - if (ti > 0) + if( ti > 0 ) { - ld.indices.Append(v2); + ld.indices.Append( v2 ); } ld.indices.Append( v1 ); @@ -220,16 +232,16 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int last = v2; } } - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB) ); - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetA + offSetB) ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetA + offSetB ) ); ld.indices.Append( last ); - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB) ); - last = ld.indices.Num()-1; + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) ); + last = ld.indices.Num() - 1; //endcap - if (ld.style.endCapStyle == 0 && ld.style.startWidth > 60) + if( ld.style.endCapStyle == 0 && ld.style.startWidth > 60 ) { - MakeCap(spld, ld, spld.edges[e], true); + MakeCap( spld, ld, spld.edges[e], true ); } } } @@ -731,7 +743,7 @@ void idSWFShapeParser::MakeLoops() break; } } - if ( shape == -1 ) + if( shape == -1 ) { idLib::Warning( "idSWFShapeParser: Hole not in a shape, try to smoothen or straighten the erroneous shape" ); fill.loops.RemoveIndexFast( hole ); @@ -1138,8 +1150,9 @@ void idSWFShapeParser::ReadFillStyle( idSWFBitStream& bitstream ) } int idx = lineDraws.Num(); lineDraws.SetNum( lineDraws.Num() + lineStyleCount ); - for ( int i = 0; i < lineStyleCount; i++ ) { - swfLineStyle_t & lineStyle = lineDraws[idx + i].style; + for( int i = 0; i < lineStyleCount; i++ ) + { + swfLineStyle_t& lineStyle = lineDraws[idx + i].style; lineStyle.startWidth = bitstream.ReadU16(); if( lineStyle2 ) { @@ -1154,14 +1167,14 @@ void idSWFShapeParser::ReadFillStyle( idSWFBitStream& bitstream ) uint8 reserved = bitstream.ReadU( 5 ); bool noClose = bitstream.ReadBool(); uint8 endCapStyle = bitstream.ReadU( 2 ); - lineStyle.endCapStyle = swfLineStyle_t::capStyle(endCapStyle); - lineStyle.startCapStyle = swfLineStyle_t::capStyle(startCapStyle); + lineStyle.endCapStyle = swfLineStyle_t::capStyle( endCapStyle ); + lineStyle.startCapStyle = swfLineStyle_t::capStyle( startCapStyle ); - if ( noClose ) + if( noClose ) { - idLib::Warning("noClose was set but Ignored."); + idLib::Warning( "noClose was set but Ignored." ); } - if ( joinStyle == 2 ) + if( joinStyle == 2 ) { uint16 miterLimitFactor = bitstream.ReadU16(); } diff --git a/neo/swf/SWF_ShapeParser.h b/neo/swf/SWF_ShapeParser.h index 027c0d5dd3..71da92f415 100644 --- a/neo/swf/SWF_ShapeParser.h +++ b/neo/swf/SWF_ShapeParser.h @@ -86,11 +86,11 @@ class idSWFShapeParser void ReadFillStyle( idSWFBitStream& bitstream ); void ParseEdge( idSWFBitStream& bitstream, int32& penX, int32& penY, swfSPEdge_t& edge ); void MakeLoops(); - void TriangulateSoup( idSWFShape & shape ); - void TriangulateSoup( idSWFFontGlyph & shape ); - int FindEarVert( const swfSPLineLoop_t & loop ); - void AddUniqueVert( idSWFShapeDrawFill & drawFill, const idVec2 & start, const idVec2 & end ); - void MakeCap( swfSPDrawLine_t & spld, idSWFShapeDrawLine &ld , swfSPMorphEdge_t & edge,bool end); + void TriangulateSoup( idSWFShape& shape ); + void TriangulateSoup( idSWFFontGlyph& shape ); + int FindEarVert( const swfSPLineLoop_t& loop ); + void AddUniqueVert( idSWFShapeDrawFill& drawFill, const idVec2& start, const idVec2& end ); + void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool end ); }; #endif // !__SWF_SHAPEPARSER_H__ diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 56a6490400..b0b90d7c82 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -57,8 +57,8 @@ idSWFSpriteInstance::idSWFSpriteInstance() : moveToSpeed( 1.0f ), stereoDepth( 0 ), actionScript( NULL ), - scriptObject ( NULL ), - constructed ( false ) + scriptObject( NULL ), + constructed( false ) { } @@ -72,16 +72,16 @@ void idSWFSpriteInstance::Init( idSWFSprite* _sprite, idSWFSpriteInstance* _pare sprite = _sprite; parent = _parent; depth = _depth; - swfMethod_info * method = nullptr; + swfMethod_info* method = nullptr; - if (actionScript && actionScript->GetMethodInfo() ) + if( actionScript && actionScript->GetMethodInfo() ) { method = actionScript->GetMethodInfo( ); } - + frameCount = sprite->frameCount; - if ( !scriptObject ) + if( !scriptObject ) { scriptObject = idSWFScriptObject::Alloc(); scriptObject->SetPrototype( &spriteInstanceScriptObjectPrototype ); @@ -92,10 +92,10 @@ void idSWFSpriteInstance::Init( idSWFSprite* _sprite, idSWFSpriteInstance* _pare firstRun = true; //this is already set if this is the main timeline - if ( !actionScript ) + if( !actionScript ) { actionScript = idSWFScriptFunction_Script::Alloc(); - idList scope; + idList scope; scope.Append( sprite->swf->globals ); scope.Append( scriptObject ); actionScript->SetScope( scope ); @@ -135,13 +135,19 @@ idSWFSpriteInstance::~idSWFSpriteInstance() idSWFSpriteInstance::FreeDisplayList ======================== */ -void idSWFSpriteInstance::FreeDisplayList() { - for ( int i = 0; i < displayList.Num(); i++ ) { +void idSWFSpriteInstance::FreeDisplayList() +{ + for( int i = 0; i < displayList.Num(); i++ ) + { - if ( displayList[i].spriteInstance ) + if( displayList[i].spriteInstance ) + { sprite->swf->spriteInstanceAllocator.Free( displayList[i].spriteInstance ); - if ( displayList[i].textInstance ) + } + if( displayList[i].textInstance ) + { sprite->swf->textInstanceAllocator.Free( displayList[i].textInstance ); + } } displayList.SetNum( 0 ); // not calling Clear() so we don't continuously re-allocate memory currentFrame = 0; @@ -198,11 +204,15 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte display.depth = depth; display.characterID = characterID; - idSWFDictionaryEntry * dictEntry = sprite->swf->FindDictionaryEntry( characterID ); - if ( dictEntry != NULL ) { - if (!dictEntry->resolved ) { - for ( auto &symbol : sprite->swf->symbolClasses.symbols ) { - if ( symbol.tag == characterID ) { + idSWFDictionaryEntry* dictEntry = sprite->swf->FindDictionaryEntry( characterID ); + if( dictEntry != NULL ) + { + if( !dictEntry->resolved ) + { + for( auto& symbol : sprite->swf->symbolClasses.symbols ) + { + if( symbol.tag == characterID ) + { dictEntry->scriptClass = sprite->swf->globals->Get( symbol.name ); dictEntry->name = &symbol.name; break; @@ -211,19 +221,19 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte dictEntry->resolved = true;//dictEntry->scriptClass != nullptr; } - if ( dictEntry->type == SWF_DICT_SPRITE ) + if( dictEntry->type == SWF_DICT_SPRITE ) { display.spriteInstance = sprite->swf->spriteInstanceAllocator.Alloc(); display.spriteInstance->abcFile = this->abcFile; - if ( dictEntry->scriptClass.IsValid() ) + if( dictEntry->scriptClass.IsValid() ) { display.spriteInstance->scriptObject = idSWFScriptObject::Alloc( ); - auto *super = dictEntry->scriptClass.GetObject( ); + auto* super = dictEntry->scriptClass.GetObject( ); - auto dcopy = super->Get("[" + *dictEntry->name + "]"); - if (dcopy.IsObject()) + auto dcopy = super->Get( "[" + *dictEntry->name + "]" ); + if( dcopy.IsObject() ) { - display.spriteInstance->scriptObject->DeepCopy(dcopy.GetObject()); + display.spriteInstance->scriptObject->DeepCopy( dcopy.GetObject() ); } display.spriteInstance->scriptObject->SetPrototype( super ); @@ -237,21 +247,22 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte display.textInstance = sprite->swf->textInstanceAllocator.Alloc(); display.textInstance->Init( dictEntry->edittext, sprite->GetSWF() ); - if ( dictEntry->scriptClass.IsValid( ) ) + if( dictEntry->scriptClass.IsValid( ) ) { - auto *super = dictEntry->scriptClass.GetObject( ); - auto dcopy = super->Get("[" + *dictEntry->name + "]"); - if (dcopy.IsObject()) + auto* super = dictEntry->scriptClass.GetObject( ); + auto dcopy = super->Get( "[" + *dictEntry->name + "]" ); + if( dcopy.IsObject() ) { - display.textInstance->scriptObject.DeepCopy(dcopy.GetObject()); - } - super->SetPrototype(display.spriteInstance->scriptObject->GetPrototype() ); + display.textInstance->scriptObject.DeepCopy( dcopy.GetObject() ); + } + super->SetPrototype( display.spriteInstance->scriptObject->GetPrototype() ); display.spriteInstance->scriptObject->SetPrototype( super ); } - - + + //display.textInstance->scriptObject.Set( "onPress", "a" ); - } else if ( dictEntry->type == SWF_DICT_TEXT ) + } + else if( dictEntry->type == SWF_DICT_TEXT ) { //display.textInstance = sprite->swf->textInstanceAllocator.Alloc( ); //display.textInstance->Init( dictEntry->text, sprite->GetSWF( ) ); @@ -265,13 +276,19 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte idSWFSpriteInstance::RemoveDisplayEntry ======================== */ -void idSWFSpriteInstance::RemoveDisplayEntry( int depth ) { - swfDisplayEntry_t * entry = FindDisplayEntry( depth ); - if ( entry != NULL ) { - if ( entry->spriteInstance ) +void idSWFSpriteInstance::RemoveDisplayEntry( int depth ) +{ + swfDisplayEntry_t* entry = FindDisplayEntry( depth ); + if( entry != NULL ) + { + if( entry->spriteInstance ) + { sprite->swf->spriteInstanceAllocator.Free( entry->spriteInstance ); - if (entry->textInstance ) + } + if( entry->textInstance ) + { sprite->swf->textInstanceAllocator.Free( entry->textInstance ); + } displayList.RemoveIndex( displayList.IndexOf( entry ) ); } } @@ -377,26 +394,32 @@ bool idSWFSpriteInstance::RunActions() actions.SetNum( 0 ); return false; } - - if (!constructed) { - if (scriptObject->HasProperty("__constructor__")) { - common->DPrintf("Calling constructor for %s%\n", name.c_str()); - idSWFScriptVar instanceInit = scriptObject->Get("__constructor__"); - if (!((idSWFScriptFunction_Script*)instanceInit.GetFunction())->GetScope()->Num()) - ((idSWFScriptFunction_Script*)instanceInit.GetFunction())->SetScope(*actionScript->GetScope()); - instanceInit.GetFunction()->Call(scriptObject, idSWFParmList()); + + if( !constructed ) + { + if( scriptObject->HasProperty( "__constructor__" ) ) + { + common->DPrintf( "Calling constructor for %s%\n", name.c_str() ); + idSWFScriptVar instanceInit = scriptObject->Get( "__constructor__" ); + if( !( ( idSWFScriptFunction_Script* )instanceInit.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )instanceInit.GetFunction() )->SetScope( *actionScript->GetScope() ); + } + instanceInit.GetFunction()->Call( scriptObject, idSWFParmList() ); constructed = true; } } - if(firstRun && !scriptObject->HasProperty("__eventDispatcher__") && scriptObject->HasProperty( "onLoad" ) ) + if( firstRun && !scriptObject->HasProperty( "__eventDispatcher__" ) && scriptObject->HasProperty( "onLoad" ) ) { firstRun = false; - idSWFScriptVar onLoad = scriptObject->Get("onLoad"); - if (!((idSWFScriptFunction_Script*)onLoad.GetFunction())->GetScope()->Num()) - ((idSWFScriptFunction_Script*)onLoad.GetFunction())->GetScope()->Append(sprite->swf->globals); - + idSWFScriptVar onLoad = scriptObject->Get( "onLoad" ); + if( !( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Append( sprite->swf->globals ); + } + onLoad.GetFunction()->Call( scriptObject, idSWFParmList() ); } @@ -427,47 +450,54 @@ bool idSWFSpriteInstance::RunActions() } } - if (firstRun && scriptObject->HasProperty("__eventDispatcher__")) { + if( firstRun && scriptObject->HasProperty( "__eventDispatcher__" ) ) + { firstRun = false; - idSWFScriptObject* eventDispatcher = scriptObject->Get("__eventDispatcher__").GetObject(); - idSWFScriptVar var = eventDispatcher->Get("addedToStage"); - if (var.IsFunction()) + idSWFScriptObject* eventDispatcher = scriptObject->Get( "__eventDispatcher__" ).GetObject(); + idSWFScriptVar var = eventDispatcher->Get( "addedToStage" ); + if( var.IsFunction() ) { idSWFScriptObject* eventObj = sprite->swf->globals - ->Get("EventDispatcher").GetObject() - ->Get("Event").GetObject() - ->Get("[Event]").GetObject(); + ->Get( "EventDispatcher" ).GetObject() + ->Get( "Event" ).GetObject() + ->Get( "[Event]" ).GetObject(); idSWFScriptVar eventParm; - eventParm.SetObject(idSWFScriptObject::Alloc()); - eventParm.GetObject()->DeepCopy(eventObj); + eventParm.SetObject( idSWFScriptObject::Alloc() ); + eventParm.GetObject()->DeepCopy( eventObj ); idSWFScriptVar eventArg; - eventArg.SetObject(idSWFScriptObject::Alloc()); - eventArg.GetObject()->Set("Event", eventParm); + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->Set( "Event", eventParm ); idSWFParmList parms; - parms.Append(eventArg); - if (!((idSWFScriptFunction_Script*)var.GetFunction())->GetScope()->Num()) - ((idSWFScriptFunction_Script*)var.GetFunction())->GetScope()->Append(sprite->swf->globals); - var.GetFunction()->Call(scriptObject, parms); + parms.Append( eventArg ); + if( !( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Append( sprite->swf->globals ); + } + var.GetFunction()->Call( scriptObject, parms ); parms.Clear(); } } //do frame scripts. - if (currentFrame && currentFrame != lastFrame && isPlaying) + if( currentFrame && currentFrame != lastFrame && isPlaying ) { - idStr frameId = idStr("frame") + idStr(currentFrame); + idStr frameId = idStr( "frame" ) + idStr( currentFrame ); idSWFScriptObject* obj = scriptObject; - if (obj && obj->HasValidProperty(frameId.c_str())) { - idSWFScriptVar frameFunc = obj->Get(frameId.c_str()); - if (frameFunc.IsFunction()) { + if( obj && obj->HasValidProperty( frameId.c_str() ) ) + { + idSWFScriptVar frameFunc = obj->Get( frameId.c_str() ); + if( frameFunc.IsFunction() ) + { idSWFScriptFunction* funcPtr = frameFunc.GetFunction(); - if (!((idSWFScriptFunction_Script*)funcPtr)->GetScope()->Num()) - ((idSWFScriptFunction_Script*)funcPtr)->SetScope(*actionScript->GetScope()); - funcPtr->Call(obj, idSWFParmList()); + if( !( ( idSWFScriptFunction_Script* )funcPtr )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )funcPtr )->SetScope( *actionScript->GetScope() ); + } + funcPtr->Call( obj, idSWFParmList() ); } } } @@ -1148,7 +1178,7 @@ idSWFScriptObject_SpriteInstancePrototype #define SWF_SPRITE_FUNCTION_SET( x ) scriptFunction_##x.AddRef(); Set( #x, &scriptFunction_##x ); #define SWF_SPRITE_NATIVE_VAR_SET( x ) SetNative( #x, &swfScriptVar_##x ); -idSWFScriptObject_SpriteInstancePrototype::idSWFScriptObject_SpriteInstancePrototype() +idSWFScriptObject_SpriteInstancePrototype::idSWFScriptObject_SpriteInstancePrototype() { SWF_SPRITE_FUNCTION_SET( addFrameScript ); SWF_SPRITE_FUNCTION_SET( duplicateMovieClip ); @@ -1238,15 +1268,16 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _height ) SWF_SPRITE_NATIVE_VAR_DEFINE_SET( _height ) { } -SWF_SPRITE_FUNCTION_DEFINE( addFrameScript ) +SWF_SPRITE_FUNCTION_DEFINE( addFrameScript ) { SWF_SPRITE_PTHIS_FUNC( "addFrameScript" ); - common->Printf("Have to add AddFrame script for frame %i\n" , parms[1].ToInteger()); + // Frame/timeline actionScript code is added implicitly return idSWFScriptVar(); } -SWF_SPRITE_FUNCTION_DEFINE( duplicateMovieClip ) { +SWF_SPRITE_FUNCTION_DEFINE( duplicateMovieClip ) +{ SWF_SPRITE_PTHIS_FUNC( "duplicateMovieClip" ); if( pThis->parent == NULL ) @@ -1632,10 +1663,11 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _name ) SWF_SPRITE_PTHIS_GET( "_name" ); return pThis->name.c_str(); } - +//Im not sure how much of the 'legacy' underscore prefixed functions need to be changed for as3.0. +//if more is needed, we should change the macro to work for both legacy AS and 3.0 SWF_SPRITE_NATIVE_VAR_DEFINE_GET( name ) { - SWF_SPRITE_PTHIS_GET("name"); + SWF_SPRITE_PTHIS_GET( "name" ); return pThis->name.c_str(); } diff --git a/neo/swf/SWF_SpriteInstance.h b/neo/swf/SWF_SpriteInstance.h index 3a147274ca..0bf6c1a8db 100644 --- a/neo/swf/SWF_SpriteInstance.h +++ b/neo/swf/SWF_SpriteInstance.h @@ -186,7 +186,7 @@ class idSWFSpriteInstance idList< swfDisplayEntry_t, TAG_SWF > displayList; swfDisplayEntry_t* FindDisplayEntry( int depth ); - SWF_AbcFile * abcFile; + SWF_AbcFile* abcFile; // name of this sprite instance idStr name; diff --git a/neo/swf/SWF_TextInstance.cpp b/neo/swf/SWF_TextInstance.cpp index eea6cf7cec..f58bb7d932 100644 --- a/neo/swf/SWF_TextInstance.cpp +++ b/neo/swf/SWF_TextInstance.cpp @@ -68,7 +68,7 @@ idSWFTextInstance::~idSWFTextInstance() subtitleTimingInfo.Clear(); } -void idSWFTextInstance::Init( idSWFText * _text, idSWF * _swf ) +void idSWFTextInstance::Init( idSWFText* _text, idSWF* _swf ) { editText = nullptr; staticText = _text; diff --git a/neo/swf/SWF_TextInstance.h b/neo/swf/SWF_TextInstance.h index 6af7cda49e..439857cbce 100644 --- a/neo/swf/SWF_TextInstance.h +++ b/neo/swf/SWF_TextInstance.h @@ -47,8 +47,8 @@ class idSWFTextInstance idSWFTextInstance(); ~idSWFTextInstance(); - void Init( idSWFEditText * _editText, idSWF * _swf ); - void Init( idSWFText * _text, idSWF *_swf ); + void Init( idSWFEditText* _editText, idSWF* _swf ); + void Init( idSWFText* _text, idSWF* _swf ); idSWFScriptObject* GetScriptObject() { @@ -176,16 +176,19 @@ class idSWFTextInstance lengthCalculated = false; } - const idSWFText * GetText() const { return staticText; } + const idSWFText* GetText() const + { + return staticText; + } // Removing the private access control statement due to cl 214702 // Apparently MS's C++ compiler supports the newer C++ standard, and GCC supports C++03 // In the new C++ standard, nested members of a friend class have access to private/protected members of the class granting friendship // In C++03, nested members defined in a friend class do NOT have access to private/protected members of the class granting friendship - idSWFEditText * editText; - idSWFText * staticText; - idSWF * swf; + idSWFEditText* editText; + idSWFText* staticText; + idSWF* swf; // this text instance's script object idSWFScriptObject scriptObject; diff --git a/neo/swf/SWF_Types.h b/neo/swf/SWF_Types.h index 5b13c7b654..c291cab3e1 100644 --- a/neo/swf/SWF_Types.h +++ b/neo/swf/SWF_Types.h @@ -164,7 +164,7 @@ struct swfLineStyle_t swfColorRGBA_t endColor; uint8 startCapStyle; uint8 endCapStyle; - enum capStyle { round = 0,none,square }; + enum capStyle { round = 0, none, square }; }; struct swfGradientRecord_t { From cf1507fd811e79ecaf0c1d1f6c9f7b13e019c232 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Tue, 21 Feb 2023 02:01:21 +0100 Subject: [PATCH 03/20] + Added swf_ExportActionScriptAPI + AS3.0 VM fixes. --- neo/swf/SWF.h | 71 ++++++++++++++------- neo/swf/SWF_Abc.cpp | 3 +- neo/swf/SWF_EventDispatcher.cpp | 4 +- neo/swf/SWF_Interpreter.cpp | 106 +++++++++++++++++++++++++++++--- neo/swf/SWF_Main.cpp | 5 +- neo/swf/SWF_PlaceObject.cpp | 20 +----- neo/swf/SWF_ScriptFunction.cpp | 21 +++++++ neo/swf/SWF_ScriptFunction.h | 7 +++ neo/swf/SWF_SpriteInstance.cpp | 4 +- 9 files changed, 184 insertions(+), 57 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index d28a082d58..c30d5d528f 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -275,40 +275,65 @@ class idSWF idBlockAlloc< idSWFSpriteInstance, 16 > spriteInstanceAllocator; idBlockAlloc< idSWFTextInstance, 16 > textInstanceAllocator; +#define SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( x ) \ + class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ + public: \ + idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ + } scriptFunction_##x; + +#define SWF_NATIVE_FUNCTION_SWF_ASAPI_DECLARE( x ) \ + class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ + public: \ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ + idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ + const char * GetActionScriptAPI( idStr & out ) ;\ + } scriptFunction_##x; + +#define SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( x, type, val ) \ + class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ + public: \ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ + idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ + const char * GetActionScriptAPI( idStr & out ) { out = "/** \n * Generated by RBDoom3BFG \n*/\npackage{\n\tpublic function "; out+= #x;out+= +"( ... parms) : ";out+=#type;out+=" { trace(\""; out+= #x; out+="( \" + parms + \" )\");return ";out+= #val;out+=";};\n}"; return #x;} \ + } scriptFunction_##x; + #define SWF_NATIVE_FUNCTION_SWF_DECLARE( x ) \ class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ public: \ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ + const char * GetActionScriptAPI( idStr & out ) { out = "/** \n * Generated by RBDoom3BFG \n*/\npackage{\n\tpublic function "; out+= #x;out+= +"( ... parms) :void { trace(\""; out+= #x; out+="( \" + parms + \" )\")};\n}"; return #x;} \ } scriptFunction_##x; - SWF_NATIVE_FUNCTION_SWF_DECLARE( shortcutKeys_clear ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( shortcutKeys_clear ); SWF_NATIVE_FUNCTION_SWF_DECLARE( deactivate ); SWF_NATIVE_FUNCTION_SWF_DECLARE( inhibitControl ); SWF_NATIVE_FUNCTION_SWF_DECLARE( useInhibit ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( precacheSound ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( precacheSound, String, parms[0] ); SWF_NATIVE_FUNCTION_SWF_DECLARE( playSound ); SWF_NATIVE_FUNCTION_SWF_DECLARE( stopSounds ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( getPlatform ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( getTruePlatform ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( getLocalString ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( swapPS3Buttons ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( getCVarInteger ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( setCVarInteger ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( strReplace ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( trace ); - - SWF_NATIVE_FUNCTION_SWF_DECLARE( acos ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( cos ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( sin ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( round ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( pow ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( sqrt ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( abs ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( rand ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( floor ); - SWF_NATIVE_FUNCTION_SWF_DECLARE( ceil ); - - SWF_NATIVE_FUNCTION_SWF_DECLARE( toUpper ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( getPlatform, Number, 2 ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( getTruePlatform, Number, 2 ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( getLocalString, String, parms[0] ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( swapPS3Buttons, Boolean, false ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( getCVarInteger, Number , 1 ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( setCVarInteger ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( strReplace, String, parms[0].replace( parms[1], parms[2] ) ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( trace ); + + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( acos, Number, Math.acos( parms[0] ) ); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( cos, Number, Math.cos( parms[0] ) ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( sin ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( round ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( pow ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( sqrt ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( abs ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( rand ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( floor ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( ceil ); + + + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( toUpper ); SWF_NATIVE_VAR_DECLARE_NESTED_READONLY( platform, idSWFScriptFunction_getPlatform, Call( object, idSWFParmList() ) ); SWF_NATIVE_VAR_DECLARE_NESTED( blackbars, idSWF ); diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index 5501ae23ca..8c67529f9d 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -269,7 +269,8 @@ void ReadConstantPoolInfo( idSWFBitStream& bitstream , swfConstant_pool_info& t target.doubles.Alloc( ) = 0.0; for( uint i = 1; i < double_count; i++ ) { - target.doubles.Alloc( ) = bitstream.ReadDouble( ); + //WARNING IEEE-754 + target.doubles.Alloc() = *( double* )bitstream.ReadData( 8 ); } uint32 string_count = bitstream.ReadEncodedU32( ); diff --git a/neo/swf/SWF_EventDispatcher.cpp b/neo/swf/SWF_EventDispatcher.cpp index 33f496f2f3..e5c6aa9933 100644 --- a/neo/swf/SWF_EventDispatcher.cpp +++ b/neo/swf/SWF_EventDispatcher.cpp @@ -154,8 +154,8 @@ SWF_EVENTDISPATCHER_FUNCTION_DEFINE( addEventListener ) dispatcher->value.SetObject( idSWFScriptObject::Alloc() ); } - dispatcher->value.GetObject()->Set( parms[1].ToString(), parms[0] ); - common->DPrintf( "{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(), parms[1].ToString().c_str(), parms[0].ToString().c_str() ); + dispatcher->value.GetObject()->Set( parms[0].ToString(), parms[1] ); + common->DPrintf( "{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(), parms[0].ToString().c_str(), parms[1].ToString().c_str() ); //add listener return idSWFScriptVar( ); } diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index 3e1ed1acc5..47a7b91171 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -379,7 +379,7 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st for( int i = 0; i < parms.Num( ); i++ ) { - parms[i] = stack.A( ); + parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); } idSWFScriptVar& item = stack.A(); @@ -553,20 +553,50 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject for( int i = 0; i < parms.Num( ); i++ ) { - parms[i] = stack.A( ); + parms[parms.Num() - 1 - i] = stack.A( ); stack.Pop( 1 ); } idSWFScriptVar& item = stack.A( ); + if( item.IsFunction( ) ) { + stack.Pop( 1 ); stack.Alloc() = item.GetFunction( )->Call( registers[0].GetObject( ), parms ); } else if( item.IsObject( ) ) { - auto func = item.GetObject( )->Get( funcName->c_str( ) ); + auto func = item.GetObject()->Get( funcName->c_str() ); + if( !func.IsFunction() ) // search up scope + { + for( int i = scope.Num() - 1; i >= 0; i-- ) + { + auto* s = scope[i]; + while( s ) + { + if( s->HasProperty( funcName->c_str() ) ) + { + func = s->Get( funcName->c_str() ); + s = NULL; + i = -1; + break; + } + else if( s->GetPrototype() && s->GetPrototype()->GetPrototype() ) + { + s = s->GetPrototype()->GetPrototype(); + } + else + { + s = NULL; + } + } + } + } if( func.IsFunction( ) ) { - ( ( idSWFScriptFunction_Script* ) func.GetFunction( ) )->SetScope( *GetScope( ) ); + if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* ) func.GetFunction( ) )->SetScope( *GetScope( ) ); + } stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); } } @@ -605,7 +635,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject for( int i = 0; i < parms.Num( ); i++ ) { - parms[i] = stack.A( ); + parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); } @@ -791,9 +821,69 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject stack.Alloc() = result; continue; } - //ExecWordCode ( subtract ); - //ExecWordCode ( multiply ); - //ExecWordCode ( divide ); + InlineWordCode( subtract ) + { + auto& lH = stack.A(); + auto& rH = stack.B(); + idSWFScriptVar result; + switch( lH.GetType( ) ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + result.SetFloat( lH.ToFloat( ) - rH.ToFloat( ) ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + result.SetInteger( lH.ToInteger( ) - rH.ToInteger( ) ); + break; + default: + common->Warning( " Tried to subtract incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + } + + stack.Pop( 2 ); + stack.Alloc() = result; + continue; + } + InlineWordCode( multiply ) + { + auto& lH = stack.A(); + auto& rH = stack.B(); + idSWFScriptVar result; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + result.SetFloat( lH.ToFloat() * rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + result.SetInteger( lH.ToInteger() * rH.ToInteger() ); + break; + default: + common->Warning( " Tried to multiply incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + + stack.Pop( 2 ); + stack.Alloc() = result; + continue; + } + InlineWordCode( divide ) + { + auto& lH = stack.A(); + auto& rH = stack.B(); + idSWFScriptVar result; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + result.SetFloat( lH.ToFloat() / rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + result.SetInteger( lH.ToInteger() / rH.ToInteger() ); + break; + default: + common->Warning( " Tried to divide incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + + stack.Pop( 2 ); + stack.Alloc() = result; + continue; + } //ExecWordCode ( modulo ); //ExecWordCode ( lshift ); //ExecWordCode ( rshift ); diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 87fbe02ef2..1aeade087a 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -118,6 +118,7 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) } idx++; } + //should remove all API scriptinfo's here. } /* @@ -174,7 +175,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, isActive = false; inhibitControl = false; - useInhibtControl = false; + useInhibtControl = true; crop = false; blackbars = false; @@ -1128,7 +1129,7 @@ void idSWF::idSWFScriptNativeVar_crop::Set( idSWFScriptObject* object, const idS idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { - common->Printf("^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", + common->Printf( "^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", parms[0].ToString().c_str() ); return idSWFScriptVar(); } diff --git a/neo/swf/SWF_PlaceObject.cpp b/neo/swf/SWF_PlaceObject.cpp index b2d8e1e1bf..9d56eca963 100644 --- a/neo/swf/SWF_PlaceObject.cpp +++ b/neo/swf/SWF_PlaceObject.cpp @@ -45,15 +45,6 @@ void idSWFSpriteInstance::PlaceObject2( idSWFBitStream& bitstream ) uint64 flags = bitstream.ReadU8(); int depth = bitstream.ReadU16(); - //if( ( flags & PlaceFlagHasClassName ) != 0 ) - //{ - // idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); - - //if( ( ( ( flags & PlaceFlagHasImage ) != 0 ) && ( ( flags & PlaceFlagHasCharacter ) != 0 ) ) ) - //{ - // idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString( ) ); - //} - //} int characterID = -1; if( ( flags & PlaceFlagHasCharacter ) != 0 ) @@ -148,7 +139,7 @@ void idSWFSpriteInstance::PlaceObject2( idSWFBitStream& bitstream ) idSWFSpriteInstance::PlaceObject3 ======================== */ -void idSWFSpriteInstance::PlaceObject3(idSWFBitStream& bitstream) +void idSWFSpriteInstance::PlaceObject3( idSWFBitStream& bitstream ) { c_PlaceObject3++; @@ -156,15 +147,6 @@ void idSWFSpriteInstance::PlaceObject3(idSWFBitStream& bitstream) uint64 flags2 = bitstream.ReadU8(); uint16 depth = bitstream.ReadU16(); - //if( ( flags2 & PlaceFlagHasClassName ) != 0 || ( flags1 & PlaceFlagHasClassName ) ) - //{ - //idLib::Warning( "PlaceObject3: hasClassName %s", bitstream.ReadString( ) ); - //if( ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) - //{ - //idLib::Warning( "PlaceObject3: %s ignored", bitstream.ReadString() ); - //} - //} - int characterID = -1; if( ( flags1 & PlaceFlagHasCharacter ) != 0 ) { diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index c530423ad2..da8fbe2692 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2015 Robert Beckebans +Copyright (C) 2022-2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -32,6 +33,26 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_debug( "swf_debug", "0", CVAR_INTEGER | CVAR_ARCHIVE, "debug swf scripts. 1 shows traces/errors. 2 also shows warnings. 3 also shows disassembly. 4 shows parameters in the disassembly." ); idCVar swf_debugInvoke( "swf_debugInvoke", "0", CVAR_INTEGER, "debug swf functions being called from game." ); +idList idSWFScriptFunction::actionScriptAPIs; +CONSOLE_COMMAND_SHIP( swf_ExportActionScriptAPI, "writes all .as files", NULL ) +{ + for( auto func : idSWFScriptFunction::actionScriptAPIs ) + { + idStr result; + idStr name = func->GetActionScriptAPI( result ); + if( !name.IsEmpty() ) + { + idStrStatic< MAX_OSPATH > generatedFileName = name; + generatedFileName.Insert( "generated/AS_Defs/", 0 ); + generatedFileName.SetFileExtension( "as" ); + idFileLocal file( fileSystem->OpenFileWrite( generatedFileName, "fs_basepath" ) ); + file->Printf( result ); + + common->Printf( "Written %s:\n ^4%s^7\n", generatedFileName.c_str(), result.c_str() ); + } + } +} + idSWFConstantPool::idSWFConstantPool() { } diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index b2012976e0..e2ae48c980 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -44,6 +44,12 @@ class idSWFScriptFunction { return idSWFScriptVar(); }; // this should never be hit + + //Used to generate [returnVal].as file with public stub function to be used while compiling actionscript 3.0 + virtual const char* GetActionScriptAPI( idStr& out ) + { + return ""; + }; virtual void AddRef() {}; virtual void Release() {}; virtual idSWFScriptObject* GetPrototype() @@ -51,6 +57,7 @@ class idSWFScriptFunction return NULL; } virtual void SetPrototype( idSWFScriptObject* _object ) { } + static idList actionScriptAPIs; }; /* diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index b0b90d7c82..ee30393ff4 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -1271,7 +1271,7 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_SET( _height ) { } SWF_SPRITE_FUNCTION_DEFINE( addFrameScript ) { SWF_SPRITE_PTHIS_FUNC( "addFrameScript" ); - // Frame/timeline actionScript code is added implicitly + // Frame/timeline actionScript code is added implicitly return idSWFScriptVar(); } @@ -1663,7 +1663,7 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _name ) SWF_SPRITE_PTHIS_GET( "_name" ); return pThis->name.c_str(); } -//Im not sure how much of the 'legacy' underscore prefixed functions need to be changed for as3.0. +//Im not sure how much of the 'legacy' underscore prefixed functions need to be changed for as3.0. //if more is needed, we should change the macro to work for both legacy AS and 3.0 SWF_SPRITE_NATIVE_VAR_DEFINE_GET( name ) { From 2978985515cfa19a89cbb680ad8d401215807c5e Mon Sep 17 00:00:00 2001 From: HarrievG Date: Fri, 24 Feb 2023 02:35:34 +0100 Subject: [PATCH 04/20] + implemented all as3.0 comparision operators + ActionscriptAPI extras --- neo/swf/SWF.h | 10 +- neo/swf/SWF_Bitstream.h | 14 +- neo/swf/SWF_Interpreter.cpp | 587 +++++++++++++++++++++++++++------ neo/swf/SWF_Main.cpp | 62 +++- neo/swf/SWF_ScriptFunction.cpp | 37 ++- neo/swf/SWF_ScriptFunction.h | 16 +- neo/swf/SWF_SpriteInstance.cpp | 2 +- 7 files changed, 616 insertions(+), 112 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index c30d5d528f..d9bee6c914 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -284,7 +284,7 @@ class idSWF #define SWF_NATIVE_FUNCTION_SWF_ASAPI_DECLARE( x ) \ class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ public: \ - idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {idSwfActionScriptAPI::actionScriptAPIs.Alloc() = this; once = true;}}\ idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ const char * GetActionScriptAPI( idStr & out ) ;\ } scriptFunction_##x; @@ -292,7 +292,7 @@ class idSWF #define SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( x, type, val ) \ class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ public: \ - idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {idSwfActionScriptAPI::actionScriptAPIs.Alloc() = this; once = true;}}\ idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ const char * GetActionScriptAPI( idStr & out ) { out = "/** \n * Generated by RBDoom3BFG \n*/\npackage{\n\tpublic function "; out+= #x;out+= +"( ... parms) : ";out+=#type;out+=" { trace(\""; out+= #x; out+="( \" + parms + \" )\");return ";out+= #val;out+=";};\n}"; return #x;} \ } scriptFunction_##x; @@ -300,12 +300,12 @@ class idSWF #define SWF_NATIVE_FUNCTION_SWF_DECLARE( x ) \ class idSWFScriptFunction_##x : public idSWFScriptFunction_Nested< idSWF > { \ public: \ - idSWFScriptFunction_##x(){ static bool once = false; if (!once) {actionScriptAPIs.Alloc() = this; once = true;}}\ + idSWFScriptFunction_##x(){ static bool once = false; if (!once) {idSwfActionScriptAPI::actionScriptAPIs.Alloc() = this; once = true;}}\ idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ); \ const char * GetActionScriptAPI( idStr & out ) { out = "/** \n * Generated by RBDoom3BFG \n*/\npackage{\n\tpublic function "; out+= #x;out+= +"( ... parms) :void { trace(\""; out+= #x; out+="( \" + parms + \" )\")};\n}"; return #x;} \ } scriptFunction_##x; - SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( shortcutKeys_clear ); + SWF_NATIVE_FUNCTION_SWF_DECLARE( shortcutKeys_clear ); SWF_NATIVE_FUNCTION_SWF_DECLARE( deactivate ); SWF_NATIVE_FUNCTION_SWF_DECLARE( inhibitControl ); SWF_NATIVE_FUNCTION_SWF_DECLARE( useInhibit ); @@ -331,7 +331,7 @@ class idSWF SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( rand ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( floor ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( ceil ); - + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE(random, Number, Math.random(parms)); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( toUpper ); diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index 0f8174af34..06e4de1c5a 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -85,7 +85,7 @@ class idSWFBitStream uint32 ReadU32(); int16 ReadS16(); int32 ReadS32(); - + int32 ReadS24(); template< typename T > T ReadEncoded() { @@ -186,6 +186,15 @@ ID_INLINE int16 idSWFBitStream::ReadS16() readp += 2; return ( readp[-2] | ( readp[-1] << 8 ) ); } + +ID_INLINE int idSWFBitStream::ReadS24() +{ + ResetBits(); + readp += 3; + uint32 i = ( readp[-3] | ( readp[-2] << 8 ) | ( readp[-1] << 16 ) ); + return ( int& )i; +} + ID_INLINE int32 idSWFBitStream::ReadS32() { ResetBits(); @@ -229,4 +238,7 @@ ID_INLINE double idSWFBitStream::ReadDouble() return d; } + + + #endif // !__SWF_BITSTREAM_H__ diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index 47a7b91171..2256ee5334 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -336,7 +336,10 @@ void idSWFScriptFunction_Script::pushscope( SWF_AbcFile* file, idSWFStack& stack { if( stack.A().IsObject() ) { - scope.Alloc() = stack.A().GetObject(); + auto stackOBj = stack.A().GetObject(); + stackOBj->AddRef(); + scope.Alloc() = stackOBj; + } else { @@ -346,11 +349,6 @@ void idSWFScriptFunction_Script::pushscope( SWF_AbcFile* file, idSWFStack& stack } } -void idSWFScriptFunction_Script::popscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) -{ - scope.SetNum( scope.Num() - 1 ); -} - void idSWFScriptFunction_Script::getlocal0( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { stack.Alloc() = registers[0]; @@ -373,6 +371,12 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st const auto& cp = file->constant_pool; const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; + + if (*funcName == "addFrameScript") + { + stack.Pop(3); + return; + } uint32 arg_count = bitstream.ReadEncodedU32(); idSWFParmList parms( arg_count ); @@ -382,6 +386,9 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); } + + + idSWFScriptVar& item = stack.A(); if( item.IsFunction() ) { @@ -425,68 +432,438 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject #define ExecWordCode( n ) case OP_##n: n(abcFile,stack,bitstream); continue; #define InlineWordCode( n ) case OP_##n: SWFAbcOpcode opCode = ( SWFAbcOpcode ) bitstream.ReadU8(); - switch( opCode ) { - //ExecWordCode ( bkpt ); - //ExecWordCode ( nop ); - //ExecWordCode ( throw ); - //ExecWordCode ( getsuper ); - //ExecWordCode ( setsuper ); - //ExecWordCode ( dxns ); - //ExecWordCode ( dxnslate ); - //ExecWordCode ( kill ); - //ExecWordCode ( label ); - //ExecWordCode ( ifnlt ); - //ExecWordCode ( ifnle ); - //ExecWordCode ( ifngt ); - //ExecWordCode ( ifnge ); - //ExecWordCode ( jump ); - //ExecWordCode ( iftrue ); - //ExecWordCode ( iffalse ); - //ExecWordCode ( ifeq ); - //ExecWordCode ( ifne ); - //ExecWordCode ( iflt ); - //ExecWordCode ( ifle ); - //ExecWordCode ( ifgt ); - //ExecWordCode ( ifge ); - //ExecWordCode ( ifstricteq ); - //ExecWordCode ( ifstrictne ); - //ExecWordCode ( lookupswitch ); - //ExecWordCode ( pushwith ); - ExecWordCode( popscope ); - //ExecWordCode ( nextname ); - //ExecWordCode ( hasnext ); + //ExecWordCode( bkpt ); + //ExecWordCode( nop ); + //ExecWordCode( throw ); + //ExecWordCode( getsuper ); + //ExecWordCode( setsuper ); + //ExecWordCode( dxns ); + //ExecWordCode( dxnslate ); + //ExecWordCode( kill ); + //ExecWordCode( label ); + InlineWordCode( ifnlt ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = !( lH.ToString() < rH.ToString() ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = !( lH.ToFloat() < rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = !( lH.ToInteger() < rH.ToInteger() ); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifnle ) + { + int offset = bitstream.ReadS24(); + const auto& lH = stack.B(); + const auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = !( lH.ToString() <= rH.ToString() ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = !( lH.ToFloat() <= rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = !( lH.ToInteger() <= rH.ToInteger() ); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifngt ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = !( lH.ToString() > rH.ToString() ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = !( lH.ToFloat() > rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = !( lH.ToInteger() > rH.ToInteger() ); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifnge ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = !( lH.ToString() >= rH.ToString() ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = !( lH.ToFloat() >= rH.ToFloat() ); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = !( lH.ToInteger() >= rH.ToInteger() ); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( jump ) + { + int offset = bitstream.ReadS24(); + bitstream.Seek( offset ); + continue; + } + InlineWordCode( iftrue ) + { + int offset = bitstream.ReadS24(); + idSWFScriptVar value = stack.A(); + stack.Pop( 1 ); + bool condition = value.ToBool(); + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( iffalse ) + { + int offset = bitstream.ReadS24(); + if( !stack.A().ToBool() ) + { + bitstream.Seek( offset ); + } + stack.Pop( 1 ); + continue; + } + InlineWordCode( ifeq ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() == rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() == rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() == rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifne ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() != rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() != rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() != rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( iflt ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() < rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() < rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() < rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifle ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() <= rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() <= rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() <= rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifgt ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() > rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() > rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() > rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifge ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + switch( lH.GetType() ) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() >= rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() >= rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() >= rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifstricteq ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + if (lH.GetType() != rH.GetType()) + { + condition = false; + } + else + { + switch (lH.GetType()) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() == rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() == rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() == rH.ToInteger(); + break; + default: + common->Warning(" Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf()); + } + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + InlineWordCode( ifstrictne ) + { + int offset = bitstream.ReadS24(); + auto& lH = stack.B(); + auto& rH = stack.A(); + stack.Pop( 2 ); + bool condition = false; + if (lH.GetType() != rH.GetType()) + { + condition = true; + } + else + { + switch (lH.GetType()) + { + case idSWFScriptVar::SWF_VAR_STRING: + condition = (lH.ToString() != rH.ToString()); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() != rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() != rH.ToInteger(); + break; + default: + common->Warning(" Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf()); + } + } + if( condition ) + { + bitstream.Seek( offset ); + } + continue; + } + //ExecWordCode( lookupswitch ); + //ExecWordCode( pushwith ); + InlineWordCode( popscope ) + { + scope.SetNum( scope.Num() - 1 ); + } + //ExecWordCode( nextname ); + //ExecWordCode( hasnext ); InlineWordCode( pushnull ) - stack.Append( idSWFScriptVar( NULL ) ); - continue; - //ExecWordCode ( pushundefined ); + { + stack.Append( idSWFScriptVar( NULL ) ); + continue; + } InlineWordCode( pushundefined ) - stack.Append( idSWFScriptVar( ) ); - continue; - //ExecWordCode ( nextvalue ); + { + stack.Append( idSWFScriptVar() ); + continue; + } + //ExecWordCode( nextvalue ); InlineWordCode( pushbyte ) - stack.Append( idSWFScriptVar( ( int )bitstream.ReadU8() ) ); - continue; + { + stack.Append( idSWFScriptVar( ( int )bitstream.ReadU8() ) ); + continue; + } InlineWordCode( pushshort ) - stack.Append( idSWFScriptVar( ( int )bitstream.ReadEncodedU32( ) ) ); - continue; + { + stack.Append( idSWFScriptVar( ( int )bitstream.ReadEncodedU32() ) ); + continue; + } InlineWordCode( pushtrue ) - stack.Append( idSWFScriptVar( true ) ); - continue; + { + stack.Append( idSWFScriptVar( true ) ); + continue; + } InlineWordCode( pushfalse ) - stack.Append( idSWFScriptVar( false ) ); - continue; + { + stack.Append( idSWFScriptVar( false ) ); + continue; + } //ExecWordCode ( pushnan ); InlineWordCode( pop ) - stack.Pop( 1 ); - continue; + { + stack.Pop( 1 ); + continue; + } InlineWordCode( dup ) - stack.Alloc() = idSWFScriptVar( stack.A() ); - continue; + { + stack.Alloc() = idSWFScriptVar( stack.A() ); + continue; + } InlineWordCode( swap ) - common->FatalError( "swap not implemented" ); - continue; + { + common->FatalError( "swap not implemented" ); + continue; + } InlineWordCode( pushstring ) { const auto& cp = abcFile->constant_pool.utf8Strings; @@ -515,30 +892,42 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject stack.Append( idSWFScriptVar( ( float )val ) ); continue; } - ExecWordCode( pushscope ); - //ExecWordCode ( pushnamespace ); - //ExecWordCode ( hasnext2 ); - //ExecWordCode ( lix8 ); - //ExecWordCode ( lix16 ); - //ExecWordCode ( li8 ); - //ExecWordCode ( li16 ); - //ExecWordCode ( li32 ); - //ExecWordCode ( lf32 ); - //ExecWordCode ( lf64 ); - //ExecWordCode ( si8 ); - //ExecWordCode ( si8 ); - //ExecWordCode ( si16 ); - //ExecWordCode ( si32 ); - //ExecWordCode ( sf32 ); - //ExecWordCode ( sf64 ); - //ExecWordCode ( newfunction ); - //ExecWordCode ( call ); - //ExecWordCode ( construct ); - //ExecWordCode ( callmethod ); - //ExecWordCode ( callstatic ); + ExecWordCode( pushscope ) + //ExecWordCode( pushnamespace ); + //ExecWordCode( hasnext2 ); + //ExecWordCode( lix8 ); + //ExecWordCode( lix16 ); + //ExecWordCode( li8 ); + //ExecWordCode( li16 ); + //ExecWordCode( li32 ); + //ExecWordCode( lf32 ); + //ExecWordCode( lf64 ); + //ExecWordCode( si8 ); + //ExecWordCode( si8 ); + //ExecWordCode( si16 ); + //ExecWordCode( si32 ); + //ExecWordCode( sf32 ); + //ExecWordCode( sf64 ); + InlineWordCode( newfunction ) + { + const auto& cp = abcFile->constant_pool; + auto& method = abcFile->methods[bitstream.ReadEncodedU32()]; + + idSWFScriptFunction_Script* func = idSWFScriptFunction_Script::Alloc(); + func->SetAbcFile( abcFile ); + func->methodInfo = &method; + func->GetScope()->Append( scope[0] ); + func->GetScope()->Append( stack.B().GetObject() ); + stack.Alloc() = idSWFScriptVar( func ); + continue; + } + InlineWordCode( call ) + InlineWordCode( construct ) + InlineWordCode( callmethod ) + InlineWordCode( callstatic ) InlineWordCode( callsuper ) { - common->FatalError( "callsuper not implemented" ); + common->FatalError( "Not implemented" ); continue; } InlineWordCode( callproperty ) @@ -612,7 +1001,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject scope.SetNum( scope.Num() - 1 ); continue; } - //ExecWordCode ( returnvalue ); + //ExecWordCode( returnvalue ); InlineWordCode( constructsuper ) { uint32 args = bitstream.ReadEncodedU32( ); @@ -647,7 +1036,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject newProp->DeepCopy( prop.GetObject() ); if( newProp->HasProperty( "__constructor__" ) ) { - common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); + //common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); idSWFScriptVar instanceInit = newProp->Get( "__constructor__" ); ( ( idSWFScriptFunction_Script* ) instanceInit.GetFunction( ) )->SetScope( *GetScope( ) ); instanceInit.GetFunction( )->Call( newProp, parms ); @@ -660,19 +1049,23 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject continue; } - //ExecWordCode ( callsuperid ); - //ExecWordCode ( callproplex ); - //ExecWordCode ( callinterface ); - //ExecWordCode ( callsupervoid ); + //ExecWordCode( callsuperid ); + //ExecWordCode( callproplex ); + //ExecWordCode( callinterface ); + //ExecWordCode( callsupervoid ); ExecWordCode( callpropvoid ); - //ExecWordCode ( sxi1 ); - //ExecWordCode ( sxi8 ); - //ExecWordCode ( sxi16 ); - //ExecWordCode ( applytype ); - //ExecWordCode ( DISABLED_pushfloat4 ); - //ExecWordCode ( newobject ); - //ExecWordCode ( newarray ); - //ExecWordCode ( newactivation ); + //ExecWordCode( sxi1 ); + //ExecWordCode( sxi8 ); + //ExecWordCode( sxi16 ); + //ExecWordCode( applytype ); + //ExecWordCode( DISABLED_pushfloat4 ); + //ExecWordCode( newarray ); + InlineWordCode( newobject ); + InlineWordCode( newactivation ) + { + stack.Alloc() = idSWFScriptObject::Alloc(); + continue; + } ExecWordCode( newclass ); //ExecWordCode ( getdescendants ); //ExecWordCode ( newcatch ); @@ -682,15 +1075,15 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( findproperty ); //ExecWordCode ( finddef ); ExecWordCode( getlex ); - InlineWordCode( setproperty ); + InlineWordCode( setproperty ) { const auto& cp = abcFile->constant_pool; const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; const auto& n = cp.utf8Strings[mn.nameIndex]; - - idSWFScriptVar value = stack.A( ); + if (stack.B().IsUndefined()) + stack.B() = idSWFScriptObject::Alloc(); + stack.B( ).GetObject( )->Set( n, stack.A() ); stack.Pop( 1 ); - stack.A( ).GetObject( )->Set( n, value ); continue; } InlineWordCode( getlocal ) @@ -971,4 +1364,4 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } abcCallstackLevel--; return idSWFScriptVar( ); -} +} \ No newline at end of file diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 1aeade087a..36d9b5cb84 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -61,7 +61,7 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) idStr& superName = abcFile.constant_pool.utf8Strings[instanceInfo.super_name->nameIndex]; //lookup prototype - if( globals->HasValidProperty( superName ) ) + if( globals->HasValidProperty( superName ) && superName != "Object" ) { tmp->SetPrototype( globals->GetObject( superName )->GetPrototype() ); } @@ -429,6 +429,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals = idSWFScriptObject::Alloc(); globals->Set( "_global", globals ); + SWF_NATIVE_API_OBJECT_DECLARE( _global ); auto* accessibilityPropertiesObj = idSWFScriptObject::Alloc( ); //accessibilityPropertiesObj->Set( "", idSWFScriptObject::Alloc( ) ); @@ -456,6 +457,9 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); globals->Set( "MovieClip", movieclipObj ); + + + CreateAbcObjects( globals ); bool skipInitOnContruct = symbolClasses.symbols.Num() > 0; @@ -489,7 +493,8 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, scriptFunction_shortcutKeys_clear.Bind( this ); scriptFunction_shortcutKeys_clear.Call( shortcutKeys, idSWFParmList() ); globals->Set( "shortcutKeys", shortcutKeys ); - + SWF_NATIVE_API_OBJECT_DECLARE( shortcutKeys ); + globals->Set( "deactivate", scriptFunction_deactivate.Bind( this ) ); globals->Set( "inhibitControl", scriptFunction_inhibitControl.Bind( this ) ); globals->Set( "useInhibit", scriptFunction_useInhibit.Bind( this ) ); @@ -506,6 +511,8 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "getCVarInteger", scriptFunction_getCVarInteger.Bind( this ) ); globals->Set( "setCVarInteger", scriptFunction_setCVarInteger.Bind( this ) ); + globals->Set( "Random", scriptFunction_random.Bind(this)); + globals->Set( "random", scriptFunction_random.Bind(this)); globals->Set( "acos", scriptFunction_acos.Bind( this ) ); globals->Set( "cos", scriptFunction_cos.Bind( this ) ); globals->Set( "sin", scriptFunction_sin.Bind( this ) ); @@ -613,6 +620,7 @@ void idSWF::Activate( bool b ) { if( !isActive && b ) { + isActive = b; inhibitControl = false; lastRenderTime = Sys_Milliseconds(); @@ -717,6 +725,11 @@ idSWF::idSWFScriptFunction_precacheSound::Call */ idSWFScriptVar idSWF::idSWFScriptFunction_precacheSound::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { + if( !parms.Num() ) + { + return "[Undefined]"; + } + const idSoundShader* soundShader = declManager->FindSound( parms[0].ToString(), true ); return soundShader->GetName(); } @@ -878,6 +891,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_setCVarInteger::Call( idSWFScriptObjec return idSWFScriptVar(); } + /* =================== idSWF::idSWFScriptFunction_acos::Call @@ -1044,6 +1058,48 @@ idSWFScriptVar idSWF::idSWFScriptFunction_ceil::Call( idSWFScriptObject* thisObj return idSWFScriptVar( idMath::Ceil( num ) ); } +/* +=================== +idSWF::idSWFScriptFunction_random::Call +=================== +*/ +idSWFScriptVar idSWF::idSWFScriptFunction_random::Call(idSWFScriptObject* thisObject, const idSWFParmList& parms) +{ + float min = 0.0f; + float max = 1.0f; + switch (parms.Num()) + { + case 0: + return 0; + break; + case 1: + switch (parms[0].GetType()) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + return pThis->GetRandom().RandomFloat() * max; + case idSWFScriptVar::SWF_VAR_INTEGER: + return pThis->GetRandom().RandomInt((int)max); + default: + return 0; + } + break; + default: + min = parms[0].ToFloat(); + max = parms[1].ToFloat(); + break; + } + + switch (parms[0].GetType()) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + return min + pThis->GetRandom().RandomFloat() * (max - min); + case idSWFScriptVar::SWF_VAR_INTEGER: + return (int)min + pThis->GetRandom().RandomInt() * (int)(max - min); + default: + return 0; + } +} + /* ======================== idSWFScriptFunction_toUpper::Call @@ -1095,7 +1151,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_shortcutKeys_clear::Call( idSWFScriptO object->Set( "MWHEELDOWN", "MWHEEL_DOWN" ); object->Set( "MWHEELUP", "MWHEEL_UP" ); object->Set( "K_TAB", "TAB" ); - + object->Set( "BACKSPACE", "BACKSPACE" ); // FIXME: I'm an RTARD and didn't realize the keys all have "ARROW" after them object->Set( "LEFTARROW", "LEFT" ); diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index da8fbe2692..510ceabfa5 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -33,17 +33,32 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_debug( "swf_debug", "0", CVAR_INTEGER | CVAR_ARCHIVE, "debug swf scripts. 1 shows traces/errors. 2 also shows warnings. 3 also shows disassembly. 4 shows parameters in the disassembly." ); idCVar swf_debugInvoke( "swf_debugInvoke", "0", CVAR_INTEGER, "debug swf functions being called from game." ); -idList idSWFScriptFunction::actionScriptAPIs; +idList idSwfActionScriptAPI::actionScriptAPIs; +idList idSwfActionScriptAPI::actionScriptVariableAPIs; +idList idSwfActionScriptAPI::actionScriptVariableNames; + +void idSwfActionScriptAPI::AddObjectAPI( idStr var ) +{ + if( !actionScriptVariableNames.Find( var ) ) + { + actionScriptVariableNames.Alloc() = var; + idStr& tmpStr = idSwfActionScriptAPI::actionScriptVariableAPIs.Alloc(); + tmpStr = "/** \n * Generated by RBDoom3BFG \n*/\npackage{\n\tpublic class "; + tmpStr += var; + tmpStr += +" extends Object{};}"; + } +} + CONSOLE_COMMAND_SHIP( swf_ExportActionScriptAPI, "writes all .as files", NULL ) { - for( auto func : idSWFScriptFunction::actionScriptAPIs ) + for( auto func : idSwfActionScriptAPI::actionScriptAPIs ) { idStr result; idStr name = func->GetActionScriptAPI( result ); if( !name.IsEmpty() ) { idStrStatic< MAX_OSPATH > generatedFileName = name; - generatedFileName.Insert( "generated/AS_Defs/", 0 ); + generatedFileName.Insert( "ActionscriptAPI/", 0 ); generatedFileName.SetFileExtension( "as" ); idFileLocal file( fileSystem->OpenFileWrite( generatedFileName, "fs_basepath" ) ); file->Printf( result ); @@ -51,6 +66,22 @@ CONSOLE_COMMAND_SHIP( swf_ExportActionScriptAPI, "writes all .as files", NULL ) common->Printf( "Written %s:\n ^4%s^7\n", generatedFileName.c_str(), result.c_str() ); } } + + for( int i = 0; i < idSwfActionScriptAPI::actionScriptVariableNames.Num(); i++ ) + { + const idStr& name = idSwfActionScriptAPI::actionScriptVariableNames[i]; + const idStr& apiStr = idSwfActionScriptAPI::actionScriptVariableAPIs[i]; + if( !name.IsEmpty() && !apiStr.IsEmpty() ) + { + idStrStatic< MAX_OSPATH > generatedFileName = name; + generatedFileName.Insert( "ActionscriptAPI/", 0 ); + generatedFileName.SetFileExtension( "as" ); + idFileLocal file( fileSystem->OpenFileWrite( generatedFileName, "fs_basepath" ) ); + file->Printf( apiStr ); + + common->Printf( "Written %s:\n ^4%s^7\n", generatedFileName.c_str(), apiStr.c_str() ); + } + } } idSWFConstantPool::idSWFConstantPool() diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index e2ae48c980..2d55b399d9 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -30,6 +30,17 @@ If you have questions concerning this license or the applicable additional terms #define __SWF_SCRIPTFUNCTION_H__ #include "SWF_Abc.h" +#define SWF_NATIVE_API_OBJECT_DECLARE( x ) idSwfActionScriptAPI::AddObjectAPI(#x); + +class idSwfActionScriptAPI +{ +public: + static idList actionScriptAPIs; + static idList actionScriptVariableAPIs; + static idList actionScriptVariableNames; + static void AddObjectAPI( idStr var ); +}; + /* ======================== Interface for calling functions from script @@ -50,6 +61,7 @@ class idSWFScriptFunction { return ""; }; + virtual void AddRef() {}; virtual void Release() {}; virtual idSWFScriptObject* GetPrototype() @@ -57,7 +69,8 @@ class idSWFScriptFunction return NULL; } virtual void SetPrototype( idSWFScriptObject* _object ) { } - static idList actionScriptAPIs; + + }; /* @@ -288,7 +301,6 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction void getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void getscopeobject( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void pushscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); - void popscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void getlocal0( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void newclass( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void callpropvoid( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index ee30393ff4..f1d8276b74 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -399,7 +399,7 @@ bool idSWFSpriteInstance::RunActions() { if( scriptObject->HasProperty( "__constructor__" ) ) { - common->DPrintf( "Calling constructor for %s%\n", name.c_str() ); + //common->DPrintf( "Calling constructor for %s%\n", name.c_str() ); idSWFScriptVar instanceInit = scriptObject->Get( "__constructor__" ); if( !( ( idSWFScriptFunction_Script* )instanceInit.GetFunction() )->GetScope()->Num() ) { From 475a486899a4909193acfd4e0678a4106c7b2703 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Sat, 25 Feb 2023 11:00:33 +0100 Subject: [PATCH 05/20] + Fix for Sprite binding in Menuhandler_pressStart --- neo/d3xp/menus/MenuHandler_Shell.cpp | 4 ++-- neo/swf/SWF.h | 5 +++++ neo/swf/SWF_Events.cpp | 2 +- neo/swf/SWF_Main.cpp | 3 ++- neo/swf/SWF_SpriteInstance.cpp | 1 + 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/neo/d3xp/menus/MenuHandler_Shell.cpp b/neo/d3xp/menus/MenuHandler_Shell.cpp index 45f018fd3e..d26a451e90 100644 --- a/neo/d3xp/menus/MenuHandler_Shell.cpp +++ b/neo/d3xp/menus/MenuHandler_Shell.cpp @@ -60,7 +60,7 @@ void idMenuHandler_Shell::Update() ClearWidgetActionRepeater(); } - if( nextState != state ) + if( nextState != state && gui->IsContructed()) { if( introGui != NULL && introGui->IsActive() ) @@ -162,7 +162,7 @@ void idMenuHandler_Shell::Update() } } - if( activeScreen != nextScreen ) + if( activeScreen != nextScreen && gui->IsContructed() ) { ClearWidgetActionRepeater(); diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index d9bee6c914..3092b96d27 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -158,6 +158,11 @@ class idSWF return *( mainspriteInstance->GetScriptObject() ); } + bool IsContructed() + { + return mainspriteInstance->constructed; + } + void Invoke( const char* functionName, const idSWFParmList& parms ); void Invoke( const char* functionName, const idSWFParmList& parms, idSWFScriptVar& scriptVar ); void Invoke( const char* functionName, const idSWFParmList& parms, bool& functionExists ); diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 5286f6a539..fb40c4de12 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -352,7 +352,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) } var.GetFunction( )->Call( hitObject, parms ); parms.Clear( ); - return false; + return true; } var = hitObject->Get( "onPress" ); diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 36d9b5cb84..52795d0aa1 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -546,6 +546,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, mainspriteInstance->Run(); mainspriteInstance->RunActions(); mainspriteInstance->RunTo( 0 ); + mainspriteInstance->constructed = true; } swf_debug.SetInteger( debug ); @@ -1151,7 +1152,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_shortcutKeys_clear::Call( idSWFScriptO object->Set( "MWHEELDOWN", "MWHEEL_DOWN" ); object->Set( "MWHEELUP", "MWHEEL_UP" ); object->Set( "K_TAB", "TAB" ); - object->Set( "BACKSPACE", "BACKSPACE" ); + object->Set( "K_BACKSPACE", "BACKSPACE" ); // FIXME: I'm an RTARD and didn't realize the keys all have "ARROW" after them object->Set( "LEFTARROW", "LEFT" ); diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index f1d8276b74..166daaa43b 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -373,6 +373,7 @@ bool idSWFSpriteInstance::Run() FreeDisplayList(); RunTo( 1 ); } + lastFrame = currentFrame; } else { From 231898da3a8c9837c6d25a1d5e479c5e2f4f1324 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Wed, 1 Mar 2023 01:49:03 +0100 Subject: [PATCH 06/20] lots of abc opcode implementations and interpretation fixes --- neo/swf/SWF.h | 5 +- neo/swf/SWF_Abc.cpp | 4 +- neo/swf/SWF_Bitstream.h | 6 +- neo/swf/SWF_Events.cpp | 1 + neo/swf/SWF_Interpreter.cpp | 490 +++++++++++++++++++++++---------- neo/swf/SWF_Main.cpp | 147 +++++++--- neo/swf/SWF_ScriptFunction.h | 1 + neo/swf/SWF_SpriteInstance.cpp | 41 ++- neo/swf/SWF_TextInstance.cpp | 6 + neo/swf/SWF_TextInstance.h | 1 + 10 files changed, 502 insertions(+), 200 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index 3092b96d27..8fdbadf295 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -325,6 +325,9 @@ class idSWF SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( setCVarInteger ); SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( strReplace, String, parms[0].replace( parms[1], parms[2] ) ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( trace ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( ArrayToString ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( registerUserMouse ); + SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( String ); SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( acos, Number, Math.acos( parms[0] ) ); SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( cos, Number, Math.cos( parms[0] ) ); @@ -336,7 +339,7 @@ class idSWF SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( rand ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( floor ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( ceil ); - SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE(random, Number, Math.random(parms)); + SWF_NATIVE_FUNCTION_SWF_ASAPI_RETURNVAL_DECLARE( random, Number, Math.random( parms ) ); SWF_NATIVE_FUNCTION_SWF_NOASAPI_DECLARE( toUpper ); diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index 8c67529f9d..fcaa55fca0 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -24,7 +24,7 @@ Copyright (C) 2022 HvanGinneken #include "SWF_Abc.h" -idCVar swf_abc_verbose( "swf_abc_verbose", "1", CVAR_INTEGER, "1 : writes out all abc data read \n 2 : print bytecode " ); +idCVar swf_abc_verbose( "swf_abc_verbose", "0", CVAR_INTEGER, "1 : writes out all abc data read \n 2 : print bytecode " ); #pragma warning( disable: 4189 ) // local variable is initialized but not referenced @@ -838,7 +838,7 @@ void idSWF::SymbolClass( idSWFBitStream& bitstream ) auto& newSymbol = symbolClasses.symbols.Alloc(); newSymbol.tag = bitstream.ReadU16( ); newSymbol.name = bitstream.ReadString( ); - common->Printf( "SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i, newSymbol.tag, newSymbol.name.c_str() ); + trace( "SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i, newSymbol.tag, newSymbol.name.c_str() ); } //load bytecode diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index 06e4de1c5a..c46f7cc48e 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -191,7 +191,11 @@ ID_INLINE int idSWFBitStream::ReadS24() { ResetBits(); readp += 3; - uint32 i = ( readp[-3] | ( readp[-2] << 8 ) | ( readp[-1] << 16 ) ); + int32 i = ( readp[-3] | ( readp[-2] << 8 ) | ( readp[-1] << 16 ) ); + if( i & ( 0x80 << 16 ) ) + { + i |= 0xff << ( 24 ); + } return ( int& )i; } diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index fb40c4de12..44b60c12f3 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -346,6 +346,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) eventArg.GetObject( )->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); + parms.Append( event->inputDevice ); if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) { ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index 2256ee5334..d0201689a5 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -270,6 +270,34 @@ void swf_PrintStream( SWF_AbcFile* file, idSWFBitStream& bitstream ) #undef ExecWordCode } +void idSWFScriptFunction_Script::findproperty( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) +{ + const auto& cp = file->constant_pool; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; + const idStrPtr propName = ( idStrPtr )&cp.utf8Strings[mn.nameIndex]; + //search up scope stack. + for( int i = scope.Num() - 1; i >= 0; i-- ) + { + auto* s = scope[i]; + while( s ) + if( s->HasProperty( propName->c_str() ) ) + { + stack.Alloc() = s->Get( propName->c_str() ); + return; + } + else if( s->GetPrototype() && s->GetPrototype()->GetPrototype() ) + { + s = s->GetPrototype()->GetPrototype(); + } + else + { + s = NULL; + } + } + auto prop = scope[0]->GetVariable( *propName, true ); + stack.Alloc() = prop->value; +} + void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { const auto& cp = file->constant_pool; @@ -295,7 +323,7 @@ void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& } } common->Warning( "idSWFScriptFunction_Script::findpropstrict cant find %s", propName->c_str() ); - //search method closure, which is the stack up until a method call? + stack.Alloc().SetObject( idSWFScriptObject::Alloc() ); } void idSWFScriptFunction_Script::getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) @@ -327,7 +355,7 @@ void idSWFScriptFunction_Script::getlex( SWF_AbcFile* file, idSWFStack& stack, i void idSWFScriptFunction_Script::getscopeobject( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { uint8 index = bitstream.ReadEncodedU32(); - stack.Alloc() = scope[scope.Num() - index]; + stack.Alloc() = scope[( scope.Num() - 1 ) - index]; } void idSWFScriptFunction_Script::pushscope( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) @@ -354,16 +382,14 @@ void idSWFScriptFunction_Script::getlocal0( SWF_AbcFile* file, idSWFStack& stack stack.Alloc() = registers[0]; } -//The class's static initializer will be run when the newclass instruction -// is executed on the class_info entry for the class. +//Classes are constructed implicitly void idSWFScriptFunction_Script::newclass( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { const auto& ci = file->classes[bitstream.ReadEncodedU32( )]; idSWFScriptVar base = stack.A(); stack.Pop( 1 ); idSWFScriptVar* thisObj = ®isters[0]; - //find static intializer. - int a = 1; + common->FatalError( "Bytestream corrupted? Classes should already be created in CreateAbcObjects()!" ); } void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) @@ -371,14 +397,15 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st const auto& cp = file->constant_pool; const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; - - if (*funcName == "addFrameScript") - { - stack.Pop(3); - return; - } + uint32 arg_count = bitstream.ReadEncodedU32(); + //Todo Optimize: search for addFrameScript string index in constantpool! + if( *funcName == "addFrameScript" ) + { + stack.Pop( arg_count ); + arg_count = 0; + } idSWFParmList parms( arg_count ); for( int i = 0; i < parms.Num( ); i++ ) @@ -386,27 +413,32 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); } - - - - idSWFScriptVar& item = stack.A(); - if( item.IsFunction() ) - { - item.GetFunction()->Call( registers[0].GetObject(), parms ); - } - else if( item.IsObject() ) + if( stack.Num() ) { - auto func = item.GetObject()->Get( funcName->c_str() ); - if( func.IsFunction( ) ) + idSWFScriptVar& item = stack.A(); + if( item.IsFunction() ) { - if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) + auto func = ( ( idSWFScriptFunction_Script* )item.GetFunction() ); + if( !func->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* )func.GetFunction() )->SetScope( *GetScope() ); + func->SetScope( *GetScope() ); } - func.GetFunction( )->Call( item.GetObject(), parms ); + item.GetFunction()->Call( registers[0].GetObject(), parms ); } + else if( item.IsObject() ) + { + auto func = item.GetObject()->Get( funcName->c_str() ); + if( func.IsFunction() ) + { + if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )func.GetFunction() )->SetScope( *GetScope() ); + } + func.GetFunction()->Call( item.GetObject(), parms ); + } + } + stack.Pop( 1 ); } - stack.Pop( 1 ); } /* @@ -417,16 +449,10 @@ idSWFScriptFunction_Script::RunAbc bytecode idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject, idSWFStack& stack, idSWFBitStream& bitstream ) { static int abcCallstackLevel = -1; - idSWFSpriteInstance* thisSprite = thisObject->GetSprite( ); - idSWFSpriteInstance* currentTarget = thisSprite; assert( abcFile ); + idSWFScriptVar returnValue; abcCallstackLevel++; - if( currentTarget == NULL ) - { - thisSprite = currentTarget = defaultSprite; - } - while( bitstream.Tell( ) < bitstream.Length( ) ) { #define ExecWordCode( n ) case OP_##n: n(abcFile,stack,bitstream); continue; @@ -435,14 +461,21 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject switch( opCode ) { //ExecWordCode( bkpt ); - //ExecWordCode( nop ); //ExecWordCode( throw ); //ExecWordCode( getsuper ); //ExecWordCode( setsuper ); //ExecWordCode( dxns ); //ExecWordCode( dxnslate ); - //ExecWordCode( kill ); - //ExecWordCode( label ); + InlineWordCode( kill ) + { + registers[bitstream.ReadEncodedU32()].SetUndefined(); + continue; + } + InlineWordCode( nop ); + InlineWordCode( label ) + { + continue; + } InlineWordCode( ifnlt ) { int offset = bitstream.ReadS24(); @@ -748,25 +781,25 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject auto& rH = stack.A(); stack.Pop( 2 ); bool condition = false; - if (lH.GetType() != rH.GetType()) + if( lH.GetType() != rH.GetType() ) { condition = false; } else { - switch (lH.GetType()) + switch( lH.GetType() ) { - case idSWFScriptVar::SWF_VAR_STRING: - condition = lH.ToString() == rH.ToString(); - break; - case idSWFScriptVar::SWF_VAR_FLOAT: - condition = lH.ToFloat() == rH.ToFloat(); - break; - case idSWFScriptVar::SWF_VAR_INTEGER: - condition = lH.ToInteger() == rH.ToInteger(); - break; - default: - common->Warning(" Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf()); + case idSWFScriptVar::SWF_VAR_STRING: + condition = lH.ToString() == rH.ToString(); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() == rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() == rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); } } if( condition ) @@ -782,25 +815,25 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject auto& rH = stack.A(); stack.Pop( 2 ); bool condition = false; - if (lH.GetType() != rH.GetType()) + if( lH.GetType() != rH.GetType() ) { condition = true; } else { - switch (lH.GetType()) + switch( lH.GetType() ) { - case idSWFScriptVar::SWF_VAR_STRING: - condition = (lH.ToString() != rH.ToString()); - break; - case idSWFScriptVar::SWF_VAR_FLOAT: - condition = lH.ToFloat() != rH.ToFloat(); - break; - case idSWFScriptVar::SWF_VAR_INTEGER: - condition = lH.ToInteger() != rH.ToInteger(); - break; - default: - common->Warning(" Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf()); + case idSWFScriptVar::SWF_VAR_STRING: + condition = ( lH.ToString() != rH.ToString() ); + break; + case idSWFScriptVar::SWF_VAR_FLOAT: + condition = lH.ToFloat() != rH.ToFloat(); + break; + case idSWFScriptVar::SWF_VAR_INTEGER: + condition = lH.ToInteger() != rH.ToInteger(); + break; + default: + common->Warning( " Tried to compare incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); } } if( condition ) @@ -814,6 +847,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject InlineWordCode( popscope ) { scope.SetNum( scope.Num() - 1 ); + continue; } //ExecWordCode( nextname ); //ExecWordCode( hasnext ); @@ -912,12 +946,12 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject { const auto& cp = abcFile->constant_pool; auto& method = abcFile->methods[bitstream.ReadEncodedU32()]; - idSWFScriptFunction_Script* func = idSWFScriptFunction_Script::Alloc(); func->SetAbcFile( abcFile ); func->methodInfo = &method; - func->GetScope()->Append( scope[0] ); - func->GetScope()->Append( stack.B().GetObject() ); + func->SetScope( scope ); + func->SetConstants( constants ); + func->SetDefaultSprite( defaultSprite ); stack.Alloc() = idSWFScriptVar( func ); continue; } @@ -991,6 +1025,11 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } continue; } + InlineWordCode(returnvalue) + { + returnValue = stack.A(); + [[fallthrough]]; + } InlineWordCode( returnvoid ) { if( scope[scope.Num() - 1] ) @@ -1001,7 +1040,6 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject scope.SetNum( scope.Num() - 1 ); continue; } - //ExecWordCode( returnvalue ); InlineWordCode( constructsuper ) { uint32 args = bitstream.ReadEncodedU32( ); @@ -1010,43 +1048,19 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } InlineWordCode( constructprop ) { - - //no need to call constructors. + //no need to call constructors for props that const auto& cp = abcFile->constant_pool; const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; uint32 arg_count = bitstream.ReadEncodedU32( ); - stack.Pop( arg_count ); - continue; - - - idSWFParmList parms( arg_count ); - - for( int i = 0; i < parms.Num( ); i++ ) - { - parms[parms.Num() - 1 - i] = stack.A(); - stack.Pop( 1 ); - } - - idSWFScriptVar prop = stack.A();//scope[0]->Get(propName->c_str()); - if( !prop.IsUndefined() && prop.IsObject() ) + if( *propName == "Array" ) { - idSWFScriptObject* newProp = idSWFScriptObject::Alloc(); - stack.Alloc() = newProp; - newProp->DeepCopy( prop.GetObject() ); - if( newProp->HasProperty( "__constructor__" ) ) + for( int i = 0; i < arg_count; i++ ) { - //common->DPrintf( "Calling constructor for %s%\n", propName->c_str( ) ); - idSWFScriptVar instanceInit = newProp->Get( "__constructor__" ); - ( ( idSWFScriptFunction_Script* ) instanceInit.GetFunction( ) )->SetScope( *GetScope( ) ); - instanceInit.GetFunction( )->Call( newProp, parms ); + stack[stack.Num() - ( arg_count + 1 )].GetObject()->Set( i, stack[stack.Num() - arg_count + i] ); } } - else - { - common->Warning( "Could not construct %s ", propName->c_str() ); - } - + stack.Pop( arg_count ); continue; } //ExecWordCode( callsuperid ); @@ -1059,11 +1073,36 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode( sxi16 ); //ExecWordCode( applytype ); //ExecWordCode( DISABLED_pushfloat4 ); - //ExecWordCode( newarray ); + InlineWordCode( newarray ) + { + auto* newArray = idSWFScriptObject::Alloc(); + + newArray->MakeArray(); + + uint32 args = bitstream.ReadEncodedU32(); + for( int i = 0; i < args; i++ ) + { + newArray->Set( i, stack.A() ); + stack.Pop( 1 ); + } + + idSWFScriptVar baseObjConstructor = scope[0]->Get( "Object" ); + idSWFScriptFunction* baseObj = baseObjConstructor.GetFunction(); + newArray->SetPrototype( baseObj->GetPrototype() ); + stack.Alloc().SetObject( newArray ); + + newArray->Release(); + continue; + } InlineWordCode( newobject ); InlineWordCode( newactivation ) { - stack.Alloc() = idSWFScriptObject::Alloc(); + idSWFScriptObject* object = idSWFScriptObject::Alloc(); + idSWFScriptVar baseObjConstructor = scope[0]->Get( "Object" ); + idSWFScriptFunction* baseObj = baseObjConstructor.GetFunction(); + object->SetPrototype( baseObj->GetPrototype() ); + stack.Alloc().SetObject( object ); + object->Release(); continue; } ExecWordCode( newclass ); @@ -1071,19 +1110,37 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( newcatch ); //ExecWordCode ( findpropglobalstrict ); //ExecWordCode ( findpropglobal ); + ExecWordCode( findproperty ); ExecWordCode( findpropstrict ); - //ExecWordCode ( findproperty ); + //ExecWordCode ( finddef ); ExecWordCode( getlex ); InlineWordCode( setproperty ) { const auto& cp = abcFile->constant_pool; - const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32()]; const auto& n = cp.utf8Strings[mn.nameIndex]; - if (stack.B().IsUndefined()) - stack.B() = idSWFScriptObject::Alloc(); - stack.B( ).GetObject( )->Set( n, stack.A() ); - stack.Pop( 1 ); + idStr index = n; + idSWFScriptObject* target = nullptr; + + if( mn.nameIndex && !stack.B().IsObject() ) + { + target = scope[0]; + } + else if( !mn.nameIndex ) + { + index = stack.B().ToString(); + idSWFScriptVar val = stack.A(); + stack.Pop( 2 ); + target = stack.A().GetObject(); + stack.Alloc() = val; + } + else if( stack.B().IsObject() ) + { + target = stack.B().GetObject(); + } + target->Set( index, stack.A() ); + stack.Pop( 2 ); continue; } InlineWordCode( getlocal ) @@ -1091,33 +1148,47 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject stack.Alloc() = registers[bitstream.ReadEncodedU32()]; continue; } - //ExecWordCode ( setlocal ); + InlineWordCode( setlocal ); + { + registers[bitstream.ReadEncodedU32()] = stack.A(); + stack.Pop( 1 ); + continue; + } //ExecWordCode ( getglobalscope ); ExecWordCode( getscopeobject ); InlineWordCode( getproperty ) { - const auto& cp = abcFile->constant_pool; - const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32()]; const auto& n = cp.utf8Strings[mn.nameIndex]; - if( !stack.A().IsObject() ) + idStr index = n; + idSWFScriptObject* target = nullptr; + + if( mn.nameIndex && !stack.A().IsObject() ) + { + target = scope[0]; + } + else if( !mn.nameIndex ) { - common->Warning( "cant find property %s", n.c_str() ); + target = stack.B().GetObject(); + index = stack.A().ToString(); stack.Pop( 1 ); - stack.Alloc().SetUndefined(); - continue; } - auto* obj = stack.A().GetObject(); + else + { + target = stack.A().GetObject(); + } + stack.Pop( 1 ); - if( obj->HasProperty( n.c_str() ) ) + if( target->HasProperty( index.c_str() ) ) { - stack.Alloc() = obj->Get( n.c_str() ); + stack.Append( target->Get( index.c_str() ) ); } else { - stack.Alloc().SetUndefined(); + stack.Alloc().SetObject( idSWFScriptObject::Alloc() ); } continue; @@ -1137,8 +1208,28 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( 0x69 ); //ExecWordCode ( deleteproperty ); //ExecWordCode ( 0x6B ); - //ExecWordCode ( getslot ); - //ExecWordCode ( setslot ); + InlineWordCode( getslot ) + { + if( stack.A().IsObject() ) + { + stack.Append( stack.A().GetObject()->Get( bitstream.ReadEncodedU32() ) ); + } + continue; + } + + InlineWordCode( setslot ) + { + auto var = stack.A(); + + if( stack.B().IsUndefined() || stack.B().IsNULL() ) + { + stack.B().SetObject( idSWFScriptObject::Alloc() ); + stack.B().GetObject()->MakeArray(); + } + + stack.B().GetObject()->Set( bitstream.ReadEncodedU32(), var ); + continue; + } //ExecWordCode ( getglobalslot ); //ExecWordCode ( setglobalslot ); //ExecWordCode ( convert_s ); @@ -1155,7 +1246,30 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( DISABLED_convert ); //ExecWordCode ( coerce ); //ExecWordCode ( coerce_b ); - //ExecWordCode ( coerce_a ); + InlineWordCode( coerce_a ) + { + auto var = stack.A(); + stack.Pop( 1 ); + if( !stack.A().IsValid() ) + { + stack.A().SetNULL(); + stack.Append( var ); + } + else + { + if( !var.IsUndefined() ) + { + stack.Append( var.ToString() ); + } + else + { + stack.Append( var ); + } + + } + + continue; + } //ExecWordCode ( coerce_i ); //ExecWordCode ( coerce_d ); //ExecWordCode ( coerce_s ); @@ -1163,7 +1277,25 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( astypelate ); //ExecWordCode ( coerce_u ); //ExecWordCode ( coerce_o ); - //ExecWordCode ( negate ); + InlineWordCode( negate_i ) + InlineWordCode( negate ) + { + auto& val = stack.A( ); + idSWFScriptVar result; + switch( val.GetType( ) ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( -val.ToFloat() ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger( -val.ToInteger() ); + continue; + default: + common->Warning( " Tried to increment incompatible type %s", val.TypeOf( ) ); + } + continue; + } + InlineWordCode( increment_i ) InlineWordCode( increment ) { auto& val = stack.A( ); @@ -1181,12 +1313,68 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } continue; } - //ExecWordCode ( inclocal ); - //ExecWordCode ( decrement ); - //ExecWordCode ( declocal ); + InlineWordCode( inclocal_i ) + InlineWordCode( inclocal ) + { + auto& val = registers[bitstream.ReadEncodedU32()]; + idSWFScriptVar result; + switch( val.GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( val.ToFloat() + 1.0f ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger( val.ToInteger() + 1 ); + continue; + default: + common->Warning( " Tried to increment incompatible type %s", val.TypeOf() ); + } + continue; + } + InlineWordCode( decrement_i ) + InlineWordCode( decrement ) + { + auto& val = stack.A(); + idSWFScriptVar result; + switch( val.GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( val.ToFloat() - 1.0f ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger( val.ToInteger() + 1 ); + continue; + default: + common->Warning( " Tried to decrement incompatible type %s", val.TypeOf() ); + } + continue; + } + InlineWordCode( declocal_i ); + InlineWordCode( declocal ); + { + auto& val = registers[bitstream.ReadEncodedU32()]; + idSWFScriptVar result; + switch( val.GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + val.SetFloat( val.ToFloat() - 1.0f ); + continue; + case idSWFScriptVar::SWF_VAR_INTEGER: + val.SetInteger( val.ToInteger() - 1 ); + continue; + default: + common->Warning( " Tried to decrement incompatible type %s", val.TypeOf() ); + } + continue; + } //ExecWordCode ( typeof ); - //ExecWordCode ( not ); + InlineWordCode( not ) + { + stack.A().SetBool( !stack.A().ToBool() ); + continue; + } //ExecWordCode ( bitnot ); + InlineWordCode( add_i ) InlineWordCode( add ) { auto& lH = stack.B(); @@ -1214,6 +1402,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject stack.Alloc() = result; continue; } + InlineWordCode( subtract_i ) InlineWordCode( subtract ) { auto& lH = stack.A(); @@ -1235,6 +1424,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject stack.Alloc() = result; continue; } + InlineWordCode( multiply_i ) InlineWordCode( multiply ) { auto& lH = stack.A(); @@ -1284,8 +1474,22 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( bitand ); //ExecWordCode ( bitor ); //ExecWordCode ( bitxor ); - //ExecWordCode ( equals ); - //ExecWordCode ( strictequals ); + InlineWordCode( equals ) + { + auto& lH = stack.A(); + auto& rH = stack.B(); + stack.Pop( 2 ); + stack.Alloc() = lH.AbstractEquals( rH ); + continue; + } + InlineWordCode( strictequals ) + { + auto& lH = stack.A(); + auto& rH = stack.B(); + stack.Pop( 2 ); + stack.Alloc() = lH.StrictEquals( rH ); + continue; + } //ExecWordCode ( lessthan ); //ExecWordCode ( lessequals ); //ExecWordCode ( greaterthan ); @@ -1294,14 +1498,6 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode ( istype ); //ExecWordCode ( istypelate ); //ExecWordCode ( in ); - //ExecWordCode ( increment_i ); - //ExecWordCode ( decrement_i ); - //ExecWordCode ( inclocal_i ); - //ExecWordCode ( declocal_i ); - //ExecWordCode ( negate_i ); - //ExecWordCode ( add_i ); - //ExecWordCode ( subtract_i ); - //ExecWordCode ( multiply_i ); InlineWordCode( getlocal0 ) { stack.Alloc() = registers[0]; @@ -1325,21 +1521,25 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject InlineWordCode( setlocal0 ) { registers[0] = stack.A(); + stack.Pop( 1 ); continue; } InlineWordCode( setlocal1 ) { registers[1] = stack.A(); + stack.Pop( 1 ); continue; } InlineWordCode( setlocal2 ) { registers[2] = stack.A(); + stack.Pop( 1 ); continue; } InlineWordCode( setlocal3 ) { registers[3] = stack.A(); + stack.Pop( 1 ); continue; } InlineWordCode( debug ) @@ -1352,16 +1552,24 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } InlineWordCode( debugline ) InlineWordCode( debugfile ) - uint32 nr = bitstream.ReadEncodedU32(); - continue; - //ExecWordCode ( bkptline ); - //ExecWordCode ( timestamp ); - //ExecWordCode ( restargc ); - //ExecWordCode ( restarg ); - //ExecWordCode ( codes ); + { + uint32 nr = bitstream.ReadEncodedU32(); + continue; + } + //ExecWordCode ( bkptline ); + //ExecWordCode ( timestamp ); + //ExecWordCode ( restargc ); + //ExecWordCode ( restarg ); + //ExecWordCode ( codes ); + default: + { + const AbcOpcodeInfo* info = &opcodeInfo[opCode]; + common->DWarning( "^5Unhandled Opcode %s\n", info ? info->name : "Empty" ); + DebugBreak(); + } } } abcCallstackLevel--; - return idSWFScriptVar( ); + return returnValue; } \ No newline at end of file diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 52795d0aa1..c28f39bad7 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2013-2015 Robert Beckebans +Copyright (C) 2022-2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -35,7 +36,7 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_loadBinary( "swf_loadBinary", "1", CVAR_INTEGER, "used to set whether to load binary swf from generated" ); -idCVar swf_printAbcObjects( "swf_printAbcObjects", "1", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag" ); +idCVar swf_printAbcObjects( "swf_printAbcObjects", "0", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag" ); int idSWF::mouseX = -1; int idSWF::mouseY = -1; @@ -57,17 +58,32 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) idSWFScriptObject* tmp = idSWFScriptObject::Alloc(); idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; //if these are namespace sets, concat all? - idStr fullClassName = *abcFile.constant_pool.namespaceNames[instanceInfo.name->index] + "." + abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; + idStr fullClassName = *abcFile.constant_pool.namespaceNames[instanceInfo.name->index]; + if( !fullClassName.IsEmpty() ) + { + fullClassName += "."; + } + fullClassName += abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; idStr& superName = abcFile.constant_pool.utf8Strings[instanceInfo.super_name->nameIndex]; //lookup prototype - if( globals->HasValidProperty( superName ) && superName != "Object" ) + if( globals->HasValidProperty( superName ) ) { - tmp->SetPrototype( globals->GetObject( superName )->GetPrototype() ); + if( superName == "Object" ) + { + idSWFScriptVar baseObjConstructor = globals->Get( "Object" ); + idSWFScriptFunction* baseObj = baseObjConstructor.GetFunction(); + tmp->SetPrototype( baseObj->GetPrototype() ); + } + else + { + tmp->SetPrototype( globals->GetObject( superName )->GetPrototype() ); + } + } else { - common->Warning( " prototype %s not found for %s", className.c_str(), superName.c_str() ); + common->Warning( " prototype %s not found for %s ", superName.c_str(), className.c_str() ); } idSWFScriptFunction_Script* init = idSWFScriptFunction_Script::Alloc(); @@ -91,11 +107,16 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) for( auto& classInfo : abcFile.classes ) { swfInstance_info& instanceInfo = abcFile.instances[idx]; - + idStr fullClassName = *abcFile.constant_pool.namespaceNames[instanceInfo.name->index]; + if( !fullClassName.IsEmpty() ) + { + fullClassName += "."; + } + fullClassName += abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; - idSWFScriptObject* tmp = globals->GetObject( className ); + idSWFScriptObject* tmp = globals->GetObject( fullClassName ); auto* target = idSWFScriptObject::Alloc( ); - auto* var = tmp->GetVariable( "[" + className + "]", true ); + auto* var = tmp->GetVariable( "[" + fullClassName + "]", true ); for( swfTraits_info& trait : instanceInfo.traits ) { @@ -111,10 +132,13 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) abcFile.GetTrait( trait, globals )->value ); } + + tmp->Set( fullClassName, target ); + if( swf_printAbcObjects.GetBool() ) { tmp->PrintToConsole( className.c_str() ); - target->PrintToConsole( "[" + className + "]" ); + target->PrintToConsole( "[" + fullClassName + "]" ); } idx++; } @@ -446,6 +470,12 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, spriteInstanceScriptObjectPrototype.SetPrototype( &eventDispatcherScriptObjectPrototype ); } + auto* arrayObj = idSWFScriptObject::Alloc(); + arrayObj->SetPrototype( scriptFunction_Object.GetPrototype() ); + arrayObj->MakeArray(); + arrayObj->Set( "toString", scriptFunction_ArrayToString.Bind( this ) ); + + globals->Set( "Array", arrayObj ); globals->Set( "Object", &scriptFunction_Object ); globals->Set( "EventDispatcher", dispatcherObj ); globals->Set( "DisplayObject", idSWFScriptObject::Alloc( ) ); @@ -457,9 +487,6 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); globals->Set( "MovieClip", movieclipObj ); - - - CreateAbcObjects( globals ); bool skipInitOnContruct = symbolClasses.symbols.Num() > 0; @@ -477,7 +504,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, mainspriteInstance->name.ExtractFileExtension( objName ); auto* super = globals->Get( symbol.name ).GetObject( ); - auto dcopy = super->Get( "[" + objName + "]" ); + auto dcopy = super->Get( "[" + symbol.name + "]" ); if( dcopy.IsObject() ) { mainspriteInstance->scriptObject->DeepCopy( dcopy.GetObject( ) ); @@ -494,7 +521,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, scriptFunction_shortcutKeys_clear.Call( shortcutKeys, idSWFParmList() ); globals->Set( "shortcutKeys", shortcutKeys ); SWF_NATIVE_API_OBJECT_DECLARE( shortcutKeys ); - + globals->Set( "deactivate", scriptFunction_deactivate.Bind( this ) ); globals->Set( "inhibitControl", scriptFunction_inhibitControl.Bind( this ) ); globals->Set( "useInhibit", scriptFunction_useInhibit.Bind( this ) ); @@ -510,9 +537,10 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "strReplace", scriptFunction_strReplace.Bind( this ) ); globals->Set( "getCVarInteger", scriptFunction_getCVarInteger.Bind( this ) ); globals->Set( "setCVarInteger", scriptFunction_setCVarInteger.Bind( this ) ); + globals->Set( "registerUserMouse", scriptFunction_registerUserMouse.Bind( this ) ); - globals->Set( "Random", scriptFunction_random.Bind(this)); - globals->Set( "random", scriptFunction_random.Bind(this)); + globals->Set( "Random", scriptFunction_random.Bind( this ) ); + globals->Set( "random", scriptFunction_random.Bind( this ) ); globals->Set( "acos", scriptFunction_acos.Bind( this ) ); globals->Set( "cos", scriptFunction_cos.Bind( this ) ); globals->Set( "sin", scriptFunction_sin.Bind( this ) ); @@ -525,6 +553,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "ceil", scriptFunction_ceil.Bind( this ) ); globals->Set( "toUpper", scriptFunction_toUpper.Bind( this ) ); globals->Set( "trace", scriptFunction_trace.Bind( this ) ); + globals->Set( "String", scriptFunction_String.Bind( this ) ); globals->SetNative( "platform", swfScriptVar_platform.Bind( &scriptFunction_getPlatform ) ); globals->SetNative( "blackbars", swfScriptVar_blackbars.Bind( this ) ); @@ -1064,40 +1093,40 @@ idSWFScriptVar idSWF::idSWFScriptFunction_ceil::Call( idSWFScriptObject* thisObj idSWF::idSWFScriptFunction_random::Call =================== */ -idSWFScriptVar idSWF::idSWFScriptFunction_random::Call(idSWFScriptObject* thisObject, const idSWFParmList& parms) +idSWFScriptVar idSWF::idSWFScriptFunction_random::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { float min = 0.0f; float max = 1.0f; - switch (parms.Num()) + switch( parms.Num() ) { - case 0: - return 0; - break; - case 1: - switch (parms[0].GetType()) - { - case idSWFScriptVar::SWF_VAR_FLOAT: - return pThis->GetRandom().RandomFloat() * max; - case idSWFScriptVar::SWF_VAR_INTEGER: - return pThis->GetRandom().RandomInt((int)max); - default: + case 0: return 0; - } - break; - default: - min = parms[0].ToFloat(); - max = parms[1].ToFloat(); - break; + break; + case 1: + switch( parms[0].GetType() ) + { + case idSWFScriptVar::SWF_VAR_FLOAT: + return pThis->GetRandom().RandomFloat() * parms[0].ToFloat(); + case idSWFScriptVar::SWF_VAR_INTEGER: + return pThis->GetRandom().RandomInt( parms[0].ToInteger() ); + default: + return 0; + } + break; + default: + min = parms[0].ToFloat(); + max = parms[1].ToFloat(); + break; } - switch (parms[0].GetType()) + switch( parms[0].GetType() ) { - case idSWFScriptVar::SWF_VAR_FLOAT: - return min + pThis->GetRandom().RandomFloat() * (max - min); - case idSWFScriptVar::SWF_VAR_INTEGER: - return (int)min + pThis->GetRandom().RandomInt() * (int)(max - min); - default: - return 0; + case idSWFScriptVar::SWF_VAR_FLOAT: + return min + pThis->GetRandom().RandomFloat() * ( max - min ); + case idSWFScriptVar::SWF_VAR_INTEGER: + return ( int )min + pThis->GetRandom().RandomInt() * ( int )( max - min ); + default: + return 0; } } @@ -1191,6 +1220,40 @@ idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call( idSWFScriptObject* thisOb return idSWFScriptVar(); } +idSWFScriptVar idSWF::idSWFScriptFunction_ArrayToString::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) +{ + idStr val; + int length = thisObject->Get( "length" ).ToInteger(); + for( int i = 0; i < length; i++ ) + { + if( i ) + { + val += ","; + } + val += thisObject->Get( i ).ToString(); + } + return val; +} + +idSWFScriptVar idSWF::idSWFScriptFunction_registerUserMouse::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) +{ + common->Printf( "^1 registerUserMouse \n" ); + + return idSWFScriptVar(); +} + + +idSWFScriptVar idSWF::idSWFScriptFunction_String::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) +{ + idStr val; + int length = parms.Num(); + for( int i = 0; i < length; i++ ) + { + val += parms[i].ToString(); + } + return val; +} + // RB begin CONSOLE_COMMAND_SHIP( exportFlash, "Export all .bswf files to the exported/swf/ folder", NULL ) { diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index 2d55b399d9..6ae57e3a85 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -297,6 +297,7 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction ////////////////////////////////////////////////////////////////////////// //////////////////////ABC Wordcode Interpretation///////////////////////// ////////////////////////////////////////////////////////////////////////// + void findproperty( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void findpropstrict( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); void getscopeobject( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ); diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 166daaa43b..5a7b6d8bb5 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -230,7 +230,7 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte display.spriteInstance->scriptObject = idSWFScriptObject::Alloc( ); auto* super = dictEntry->scriptClass.GetObject( ); - auto dcopy = super->Get( "[" + *dictEntry->name + "]" ); + auto dcopy = super->Get( *dictEntry->name ); if( dcopy.IsObject() ) { display.spriteInstance->scriptObject->DeepCopy( dcopy.GetObject() ); @@ -250,7 +250,7 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte if( dictEntry->scriptClass.IsValid( ) ) { auto* super = dictEntry->scriptClass.GetObject( ); - auto dcopy = super->Get( "[" + *dictEntry->name + "]" ); + auto dcopy = super->Get( *dictEntry->name ); if( dcopy.IsObject() ) { display.textInstance->scriptObject.DeepCopy( dcopy.GetObject() ); @@ -373,7 +373,10 @@ bool idSWFSpriteInstance::Run() FreeDisplayList(); RunTo( 1 ); } - lastFrame = currentFrame; + else + { + lastFrame = currentFrame; + } } else { @@ -411,7 +414,6 @@ bool idSWFSpriteInstance::RunActions() } } - if( firstRun && !scriptObject->HasProperty( "__eventDispatcher__" ) && scriptObject->HasProperty( "onLoad" ) ) { firstRun = false; @@ -443,13 +445,6 @@ bool idSWFSpriteInstance::RunActions() Prefetch( displayList[i].spriteInstance, 0 ); } } - for( int i = 0; i < displayList.Num(); i++ ) - { - if( displayList[i].spriteInstance != NULL ) - { - displayList[i].spriteInstance->RunActions(); - } - } if( firstRun && scriptObject->HasProperty( "__eventDispatcher__" ) ) { @@ -503,6 +498,14 @@ bool idSWFSpriteInstance::RunActions() } } + for( int i = 0; i < displayList.Num(); i++ ) + { + if( displayList[i].spriteInstance != NULL ) + { + displayList[i].spriteInstance->RunActions(); + } + } + firstRun = false; return true; } @@ -589,7 +592,11 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) for( uint32 c = sprite->frameOffsets[ currentFrame ]; c < sprite->frameOffsets[ targetFrame ]; c++ ) { idSWFSprite::swfSpriteCommand_t& command = sprite->commands[ c ]; - if( command.tag == Tag_DoAction && c < firstActionCommand ) + + idStr frameId = idStr( "frame" ) + c; + idSWFScriptObject* obj = scriptObject; + bool hasAction = ( obj && obj->HasValidProperty( frameId.c_str() ) ); + if( ( hasAction || command.tag == Tag_DoAction ) && c < firstActionCommand ) { // Skip DoAction up to the firstActionCommand // This is to properly support skipping to a specific frame @@ -612,6 +619,13 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) idLib::Printf( "Run Sprite: Unhandled tag %s\n", idSWF::GetTagName( command.tag ) ); } } + idStr frameId = idStr( "frame" ) + targetFrame; + idSWFScriptObject* obj = scriptObject; + if( obj && obj->HasValidProperty( frameId.c_str() ) ) + { + RunActions(); + } + lastFrame = currentFrame; currentFrame = targetFrame; } @@ -1323,8 +1337,9 @@ SWF_SPRITE_FUNCTION_DEFINE( gotoAndPlay ) if( parms.Num() > 0 ) { + uint32 targetFrame = pThis->FindFrame( parms[0].ToString() ); pThis->actions.Clear(); - pThis->RunTo( pThis->FindFrame( parms[0].ToString() ) ); + pThis->RunTo( targetFrame ); pThis->Play(); } else diff --git a/neo/swf/SWF_TextInstance.cpp b/neo/swf/SWF_TextInstance.cpp index f58bb7d932..836d2f46de 100644 --- a/neo/swf/SWF_TextInstance.cpp +++ b/neo/swf/SWF_TextInstance.cpp @@ -1102,6 +1102,7 @@ idSWFScriptObject_TextInstancePrototype::idSWFScriptObject_TextInstancePrototype SWF_TEXT_NATIVE_VAR_SET( text ); SWF_TEXT_NATIVE_VAR_SET( _textLength ); // only works on single lines of text not multiline + SWF_TEXT_NATIVE_VAR_SET( length ); // only works on single lines of text not multiline SWF_TEXT_NATIVE_VAR_SET( autoSize ); SWF_TEXT_NATIVE_VAR_SET( dropShadow ); SWF_TEXT_NATIVE_VAR_SET( _stroke ); @@ -1326,6 +1327,11 @@ SWF_TEXT_NATIVE_VAR_DEFINE_GET( _textLength ) SWF_TEXT_PTHIS_GET( "_textLength" ); return pThis->GetTextLength(); } +SWF_TEXT_NATIVE_VAR_DEFINE_GET( length ) +{ + SWF_TEXT_PTHIS_GET( "length" ); + return pThis->GetTextLength(); +} SWF_TEXT_NATIVE_VAR_DEFINE_SET( mode ) { diff --git a/neo/swf/SWF_TextInstance.h b/neo/swf/SWF_TextInstance.h index 439857cbce..d2660e97fd 100644 --- a/neo/swf/SWF_TextInstance.h +++ b/neo/swf/SWF_TextInstance.h @@ -323,6 +323,7 @@ class idSWFScriptObject_TextInstancePrototype : public idSWFScriptObject SWF_NATIVE_VAR_DECLARE( subtitleSpeaker ); SWF_NATIVE_VAR_DECLARE_READONLY( _textLength ); + SWF_NATIVE_VAR_DECLARE_READONLY( length ); SWF_TEXT_FUNCTION_DECLARE( subtitleSourceCheck ); SWF_TEXT_FUNCTION_DECLARE( subtitleStart ); From 0472adc9ca169c7f40dd1d786828c3ff872c1c26 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Thu, 2 Mar 2023 01:28:40 +0100 Subject: [PATCH 07/20] - Corrected ABC code execution order --- neo/swf/SWF_Interpreter.cpp | 10 ++- neo/swf/SWF_Main.cpp | 4 +- neo/swf/SWF_SpriteInstance.cpp | 135 ++++++++++++++++----------------- neo/swf/SWF_SpriteInstance.h | 2 + 4 files changed, 78 insertions(+), 73 deletions(-) diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index d0201689a5..8dbc7b57cf 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -452,6 +452,14 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject assert( abcFile ); idSWFScriptVar returnValue; + idSWFSpriteInstance* thisSprite = thisObject->GetSprite(); + idSWFSpriteInstance* currentTarget = thisSprite; + + if( currentTarget == NULL ) + { + thisSprite = currentTarget = defaultSprite; + } + abcCallstackLevel++; while( bitstream.Tell( ) < bitstream.Length( ) ) { @@ -1025,7 +1033,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } continue; } - InlineWordCode(returnvalue) + InlineWordCode( returnvalue ) { returnValue = stack.A(); [[fallthrough]]; diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index c28f39bad7..96c8508d93 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -493,8 +493,8 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, mainspriteInstance = spriteInstanceAllocator.Alloc(); mainspriteInstance->abcFile = &abcFile; mainspriteInstance->scriptObject = idSWFScriptObject::Alloc( ); - //stage class. + //stage class. for( auto& symbol : symbolClasses.symbols ) { if( !symbol.tag ) @@ -563,6 +563,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, // Do this to touch any external references (like sounds) // But disable script warnings because many globals won't have been created yet + // THIS DOES NOT APPLY TO AS3. extern idCVar swf_debug; int debug = swf_debug.GetInteger(); swf_debug.SetInteger( 0 ); @@ -650,7 +651,6 @@ void idSWF::Activate( bool b ) { if( !isActive && b ) { - isActive = b; inhibitControl = false; lastRenderTime = Sys_Milliseconds(); diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 5a7b6d8bb5..3c50c6e74b 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -95,7 +95,7 @@ void idSWFSpriteInstance::Init( idSWFSprite* _sprite, idSWFSpriteInstance* _pare if( !actionScript ) { actionScript = idSWFScriptFunction_Script::Alloc(); - idList scope; + idList scope; scope.Append( sprite->swf->globals ); scope.Append( scriptObject ); actionScript->SetScope( scope ); @@ -151,7 +151,6 @@ void idSWFSpriteInstance::FreeDisplayList() } displayList.SetNum( 0 ); // not calling Clear() so we don't continuously re-allocate memory currentFrame = 0; - lastFrame = 0; } /* @@ -373,10 +372,6 @@ bool idSWFSpriteInstance::Run() FreeDisplayList(); RunTo( 1 ); } - else - { - lastFrame = currentFrame; - } } else { @@ -396,6 +391,7 @@ bool idSWFSpriteInstance::RunActions() if( !isVisible ) { actions.SetNum( 0 ); + functionActions.SetNum( 0 ); return false; } @@ -414,16 +410,50 @@ bool idSWFSpriteInstance::RunActions() } } - if( firstRun && !scriptObject->HasProperty( "__eventDispatcher__" ) && scriptObject->HasProperty( "onLoad" ) ) + if( firstRun && ( scriptObject->HasProperty( "__eventDispatcher__" ) || scriptObject->HasProperty( "onLoad" ) ) ) { firstRun = false; idSWFScriptVar onLoad = scriptObject->Get( "onLoad" ); - if( !( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Num() ) + if( onLoad.IsValid() ) { - ( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Append( sprite->swf->globals ); + if( !( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )onLoad.GetFunction() )->GetScope()->Append( sprite->swf->globals ); + } + + onLoad.GetFunction()->Call( scriptObject, idSWFParmList() ); } - onLoad.GetFunction()->Call( scriptObject, idSWFParmList() ); + if( scriptObject->HasProperty( "__eventDispatcher__" ) ) + { + idSWFScriptObject* eventDispatcher = scriptObject->Get( "__eventDispatcher__" ).GetObject(); + idSWFScriptVar var = eventDispatcher->Get( "addedToStage" ); + if( var.IsFunction() ) + { + + idSWFScriptObject* eventObj = sprite->swf->globals + ->Get( "EventDispatcher" ).GetObject() + ->Get( "Event" ).GetObject() + ->Get( "[Event]" ).GetObject(); + + idSWFScriptVar eventParm; + eventParm.SetObject( idSWFScriptObject::Alloc() ); + eventParm.GetObject()->DeepCopy( eventObj ); + + idSWFScriptVar eventArg; + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->Set( "Event", eventParm ); + + idSWFParmList parms; + parms.Append( eventArg ); + if( !( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Append( sprite->swf->globals ); + } + var.GetFunction()->Call( scriptObject, parms ); + parms.Clear(); + } + } } if( onEnterFrame.IsFunction() ) @@ -438,63 +468,17 @@ bool idSWFSpriteInstance::RunActions() } actions.SetNum( 0 ); - for( int i = 0; i < displayList.Num(); i++ ) - { - if( displayList[i].spriteInstance != NULL ) - { - Prefetch( displayList[i].spriteInstance, 0 ); - } - } - - if( firstRun && scriptObject->HasProperty( "__eventDispatcher__" ) ) + for ( int i = 0; i < functionActions.Num(); i++ ) { - firstRun = false; - idSWFScriptObject* eventDispatcher = scriptObject->Get( "__eventDispatcher__" ).GetObject(); - idSWFScriptVar var = eventDispatcher->Get( "addedToStage" ); - if( var.IsFunction() ) - { - - idSWFScriptObject* eventObj = sprite->swf->globals - ->Get( "EventDispatcher" ).GetObject() - ->Get( "Event" ).GetObject() - ->Get( "[Event]" ).GetObject(); - - idSWFScriptVar eventParm; - eventParm.SetObject( idSWFScriptObject::Alloc() ); - eventParm.GetObject()->DeepCopy( eventObj ); - - idSWFScriptVar eventArg; - eventArg.SetObject( idSWFScriptObject::Alloc() ); - eventArg.GetObject()->Set( "Event", eventParm ); - - idSWFParmList parms; - parms.Append( eventArg ); - if( !( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Num() ) - { - ( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Append( sprite->swf->globals ); - } - var.GetFunction()->Call( scriptObject, parms ); - parms.Clear(); - } + functionActions[i]->Call( scriptObject, idSWFParmList() ); } + functionActions.SetNum( 0 ); - //do frame scripts. - if( currentFrame && currentFrame != lastFrame && isPlaying ) + for( int i = 0; i < displayList.Num(); i++ ) { - idStr frameId = idStr( "frame" ) + idStr( currentFrame ); - idSWFScriptObject* obj = scriptObject; - if( obj && obj->HasValidProperty( frameId.c_str() ) ) + if( displayList[i].spriteInstance != NULL ) { - idSWFScriptVar frameFunc = obj->Get( frameId.c_str() ); - if( frameFunc.IsFunction() ) - { - idSWFScriptFunction* funcPtr = frameFunc.GetFunction(); - if( !( ( idSWFScriptFunction_Script* )funcPtr )->GetScope()->Num() ) - { - ( ( idSWFScriptFunction_Script* )funcPtr )->SetScope( *actionScript->GetScope() ); - } - funcPtr->Call( obj, idSWFParmList() ); - } + Prefetch( displayList[i].spriteInstance, 0 ); } } @@ -506,7 +490,6 @@ bool idSWFSpriteInstance::RunActions() } } - firstRun = false; return true; } @@ -593,10 +576,7 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) { idSWFSprite::swfSpriteCommand_t& command = sprite->commands[ c ]; - idStr frameId = idStr( "frame" ) + c; - idSWFScriptObject* obj = scriptObject; - bool hasAction = ( obj && obj->HasValidProperty( frameId.c_str() ) ); - if( ( hasAction || command.tag == Tag_DoAction ) && c < firstActionCommand ) + if( command.tag == Tag_DoAction && c < firstActionCommand ) { // Skip DoAction up to the firstActionCommand // This is to properly support skipping to a specific frame @@ -619,14 +599,24 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) idLib::Printf( "Run Sprite: Unhandled tag %s\n", idSWF::GetTagName( command.tag ) ); } } - idStr frameId = idStr( "frame" ) + targetFrame; + + idStr frameId = idStr( "frame" ) + targetFrame ; idSWFScriptObject* obj = scriptObject; if( obj && obj->HasValidProperty( frameId.c_str() ) ) { - RunActions(); + idSWFScriptVar frameFunc = obj->Get( frameId.c_str() ); + if( frameFunc.IsFunction() ) + { + idSWFScriptFunction* funcPtr = frameFunc.GetFunction(); + if( !( ( idSWFScriptFunction_Script* )funcPtr )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )funcPtr )->SetScope( *actionScript->GetScope() ); + } + DoAction( funcPtr ); + } + } - lastFrame = currentFrame; currentFrame = targetFrame; } @@ -644,6 +634,11 @@ void idSWFSpriteInstance::DoAction( idSWFBitStream& bitstream ) #endif } +void idSWFSpriteInstance::DoAction( idSWFScriptFunction* function ) +{ + functionActions.Alloc() = function; +} + /* ======================== idSWFSpriteInstance::FindChildSprite diff --git a/neo/swf/SWF_SpriteInstance.h b/neo/swf/SWF_SpriteInstance.h index 0bf6c1a8db..e14b60924e 100644 --- a/neo/swf/SWF_SpriteInstance.h +++ b/neo/swf/SWF_SpriteInstance.h @@ -196,6 +196,7 @@ class idSWFSpriteInstance uint32 dataLength; }; idList< swfAction_t, TAG_SWF > actions; + idList< idSWFScriptFunction*, TAG_SWF > functionActions; idSWFScriptFunction_Script* actionScript; @@ -235,6 +236,7 @@ class idSWFSpriteInstance void SwapDepths( int depth1, int depth2 ); void DoAction( idSWFBitStream& bitstream ); + void DoAction( idSWFScriptFunction* function ); idSWFSpriteInstance* FindChildSprite( const char* childName ); idSWFSpriteInstance* ResolveTarget( const char* targetName ); From c0fe40174a98dde68d9984e8319a8d13494ef018 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Fri, 3 Mar 2023 00:44:41 +0100 Subject: [PATCH 08/20] + binary writing and loading of bswf now supports abc and symbol tag info --- neo/swf/SWF_Abc.cpp | 29 +++++++++++++++++++++-------- neo/swf/SWF_Abc.h | 7 +++++++ neo/swf/SWF_Bitstream.cpp | 13 +++++++++++++ neo/swf/SWF_Bitstream.h | 1 + neo/swf/SWF_Load.cpp | 29 +++++++++++++++++++++++++++-- neo/swf/SWF_Main.cpp | 5 +---- neo/swf/SWF_SpriteInstance.cpp | 2 +- 7 files changed, 71 insertions(+), 15 deletions(-) diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index fcaa55fca0..48649bbe27 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -205,6 +205,7 @@ void SWF_AbcFile::traceConstantPool( swfConstant_pool_info& constant_pool ) trace( "^8========================================================\n" ); } + void ReadMultiName( idSWFBitStream& bitstream , swfMultiname& target ) { target.type = ( swfConstantKind_t )bitstream.ReadU8(); @@ -746,13 +747,31 @@ void SWF_AbcFile::ReadMethodInfo( idSWFBitStream& bitstream , swfMethod_info& ne } -//Remove Accessibility -void idSWF::DoABC( idSWFBitStream& bitstream ) +void SWF_AbcFile::WriteBinary( idFileLocal& file ) { + file->WriteBig( ( int )AbcTagData.Length() ); + file->Write( AbcTagData.Ptr(), AbcTagData.Length() ); +} +void SWF_AbcFile::LoadBinary( idFile* file ) +{ + uint32 len; + file->ReadBig( len ); + AbcTagData.LoadFromFile( file, len ); +} + +//Remove Accessibility +void idSWF::DoABC( idSWFBitStream& bitstream ) +{ SWF_AbcFile& newAbcFile = abcFile; int strmSize = bitstream.Length( ) + 6; // codeLength(uin16) + recordLength(uin32) + + if( !newAbcFile.AbcTagData.Length() ) + { + newAbcFile.AbcTagData.Load( bitstream.Ptr(), bitstream.Length(), true ); + } + uint32 flags = bitstream.ReadU32(); idStr name = bitstream.ReadString(); int dataSize = bitstream.Length( ) - name.Length( ); @@ -813,13 +832,9 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) trace( "methBody_count %i \n", methBody_count ); for( uint i = 0; i < methBody_count; i++ ) { - auto& newMethBody = newAbcFile.method_bodies[i]; newAbcFile.ReadMethodBodyInfo( bitstream, newMethBody ); } - - //Create trait objects - //resolve subclass/superclass relations. } void idSWF::SymbolClass( idSWFBitStream& bitstream ) @@ -840,8 +855,6 @@ void idSWF::SymbolClass( idSWFBitStream& bitstream ) newSymbol.name = bitstream.ReadString( ); trace( "SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i, newSymbol.tag, newSymbol.name.c_str() ); } - - //load bytecode } diff --git a/neo/swf/SWF_Abc.h b/neo/swf/SWF_Abc.h index 82cf90a33a..c94dda07e6 100644 --- a/neo/swf/SWF_Abc.h +++ b/neo/swf/SWF_Abc.h @@ -201,6 +201,13 @@ struct SWF_AbcFile idList classes; //class_info class[class_count] idList scripts; //u30 script_count script_info script[script_count] idList method_bodies; //u30 method_body_count method_body_info method_body[method_body_count] + + //Writing the whole bytestream as whole for now, but : + // debug info plus unused tags and bytecode should be removed, constant pools need to stay the same + // accessibility can also be removed. + idSWFBitStream AbcTagData; + void WriteBinary( idFileLocal& file ); + void LoadBinary( idFile* file ); }; struct SWF_SymbolClass diff --git a/neo/swf/SWF_Bitstream.cpp b/neo/swf/SWF_Bitstream.cpp index 68d169850f..b3b2f32906 100644 --- a/neo/swf/SWF_Bitstream.cpp +++ b/neo/swf/SWF_Bitstream.cpp @@ -61,6 +61,19 @@ idSWFBitStream::idSWFBitStream() Free(); } +void idSWFBitStream::LoadFromFile( idFile* file, uint32 len ) +{ + Free(); + free = true; + startp = ( const byte* )Mem_Alloc( len, TAG_SWF ); + file->Read( ( byte* )startp, len ); + + endp = startp + len; + readp = startp; + + ResetBits(); +} + /* ======================== idSWFBitStream::operator= diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index c46f7cc48e..b823c748c8 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -45,6 +45,7 @@ class idSWFBitStream idSWFBitStream& operator=( idSWFBitStream& other ); idSWFBitStream& operator=( idSWFBitStream&& other ); + void LoadFromFile( idFile* file, uint32 len ); void Load( const byte* data, uint32 len, bool copy ); void Free(); const byte* Ptr() diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 71dabec6cd..2905fb04a9 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -38,8 +38,9 @@ using namespace rapidjson;//bleh idCVar swf_fatalVersionMismatch( "swf_fatalVersionMismatch", "0", CVAR_BOOL, "Version number mismatch results in fatal error" ); - -#define BSWF_VERSION 16 // bumped to 16 for storing atlas image dimensions for unbuffered loads +// bumped to 16 for storing atlas image dimensions for unbuffered loads +// should be bumped to 17 for storing ABC Tag +#define BSWF_VERSION 16 #define BSWF_MAGIC ( ( 'B' << 24 ) | ( 'S' << 16 ) | ( 'W' << 8 ) | BSWF_VERSION ) // RB begin @@ -620,6 +621,22 @@ bool idSWF::LoadBinary( const char* bfilename, ID_TIME_T sourceTimeStamp ) } } } + + if( f->Tell() < f->Length() ) + { + abcFile.LoadBinary( f ); + + f->ReadBig( num ); + symbolClasses.symbols.SetNum( num ); + for( int i = 0; i < symbolClasses.symbols.Num(); i++ ) + { + f->ReadBig( symbolClasses.symbols[i].tag ); + f->ReadString( symbolClasses.symbols[i].name ); + } + + DoABC( abcFile.AbcTagData ); + } + delete f; return true; @@ -796,6 +813,14 @@ void idSWF::WriteBinary( const char* bfilename ) } } } + + abcFile.WriteBinary( file ); + file->WriteBig( symbolClasses.symbols.Num() ); + for( int i = 0; i < symbolClasses.symbols.Num(); i++ ) + { + file->WriteBig( symbolClasses.symbols[i].tag ); + file->WriteString( symbolClasses.symbols[i].name ); + } } diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 96c8508d93..d4b42deddc 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -260,10 +260,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, } else if( LoadSWF( filename ) ) { - if( !abcFile.class_count ) - { - WriteBinary( binaryFileName ); - } + WriteBinary( binaryFileName ); } } } diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 3c50c6e74b..217728f57d 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -468,7 +468,7 @@ bool idSWFSpriteInstance::RunActions() } actions.SetNum( 0 ); - for ( int i = 0; i < functionActions.Num(); i++ ) + for( int i = 0; i < functionActions.Num(); i++ ) { functionActions[i]->Call( scriptObject, idSWFParmList() ); } From 2388fc663a8378c26f918361bb1d03644a347a5f Mon Sep 17 00:00:00 2001 From: HarrievG Date: Tue, 7 Mar 2023 00:51:43 +0100 Subject: [PATCH 09/20] Various mem leak fixes for as3.0 --- neo/swf/SWF.h | 5 +++-- neo/swf/SWF_Events.cpp | 1 + neo/swf/SWF_Interpreter.cpp | 24 +++++++----------------- neo/swf/SWF_Main.cpp | 17 ++++++++++------- neo/swf/SWF_ScriptFunction.cpp | 11 ++++++----- neo/swf/SWF_SpriteInstance.cpp | 30 ++++++++++++++---------------- 6 files changed, 41 insertions(+), 47 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index 8fdbadf295..4605196ff6 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -225,7 +225,8 @@ class idSWF idSWFScriptObject* HitTest( idSWFSpriteInstance* spriteInstance, const swfRenderState_t& renderState, int x, int y, idSWFScriptObject* parentObject ); - SWF_AbcFile abcFile; + SWF_AbcFile abcFile; + static bool isMouseInClientArea; private: idStr filename; ID_TIME_T timestamp; @@ -262,7 +263,7 @@ class idSWF static int mouseX; // mouse x coord for all flash files static int mouseY; // mouse y coord for all flash files - static bool isMouseInClientArea; + idSWFScriptObject* mouseObject; idSWFScriptObject* hoverObject; diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 44b60c12f3..187e008101 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -421,6 +421,7 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) idSWFParmList parms; parms.Append( mouseObject ); // FIXME: Remove this var.GetFunction()->Call( mouseObject, parms ); + parms.Clear(); } mouseObject->Release(); mouseObject = NULL; diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index 8dbc7b57cf..e2da5be6f7 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -324,6 +324,7 @@ void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& } common->Warning( "idSWFScriptFunction_Script::findpropstrict cant find %s", propName->c_str() ); stack.Alloc().SetObject( idSWFScriptObject::Alloc() ); + stack.A().GetObject()->Release(); } void idSWFScriptFunction_Script::getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) @@ -418,11 +419,6 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st idSWFScriptVar& item = stack.A(); if( item.IsFunction() ) { - auto func = ( ( idSWFScriptFunction_Script* )item.GetFunction() ); - if( !func->GetScope()->Num() ) - { - func->SetScope( *GetScope() ); - } item.GetFunction()->Call( registers[0].GetObject(), parms ); } else if( item.IsObject() ) @@ -430,10 +426,6 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st auto func = item.GetObject()->Get( funcName->c_str() ); if( func.IsFunction() ) { - if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) - { - ( ( idSWFScriptFunction_Script* )func.GetFunction() )->SetScope( *GetScope() ); - } func.GetFunction()->Call( item.GetObject(), parms ); } } @@ -854,6 +846,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode( pushwith ); InlineWordCode( popscope ) { + scope[scope.Num() - 1]->Release(); scope.SetNum( scope.Num() - 1 ); continue; } @@ -910,7 +903,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject { const auto& cp = abcFile->constant_pool.utf8Strings; const auto& mn = cp[bitstream.ReadEncodedU32( )]; - stack.Append( idSWFScriptString( mn.c_str() ) ); + stack.Append( idSWFScriptString( mn ) ); continue; } InlineWordCode( pushint ) @@ -961,6 +954,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject func->SetConstants( constants ); func->SetDefaultSprite( defaultSprite ); stack.Alloc() = idSWFScriptVar( func ); + stack.A().GetFunction()->Release(); continue; } InlineWordCode( call ) @@ -1024,10 +1018,6 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } if( func.IsFunction( ) ) { - if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) - { - ( ( idSWFScriptFunction_Script* ) func.GetFunction( ) )->SetScope( *GetScope( ) ); - } stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); } } @@ -1040,12 +1030,11 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } InlineWordCode( returnvoid ) { - if( scope[scope.Num() - 1] ) + if( scope.Num() ) { scope[scope.Num() - 1]->Release(); + scope.SetNum( scope.Num() - 1 ); } - - scope.SetNum( scope.Num() - 1 ); continue; } InlineWordCode( constructsuper ) @@ -1197,6 +1186,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject else { stack.Alloc().SetObject( idSWFScriptObject::Alloc() ); + stack.A().GetObject()->Release(); } continue; diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index d4b42deddc..72a6da22d6 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -37,6 +37,7 @@ If you have questions concerning this license or the applicable additional terms idCVar swf_loadBinary( "swf_loadBinary", "1", CVAR_INTEGER, "used to set whether to load binary swf from generated" ); idCVar swf_printAbcObjects( "swf_printAbcObjects", "0", CVAR_INTEGER, "used to set whether to print all classes constructed from the DoAbc tag" ); +idCVar swf_enableAbcTrace( "swf_enableAbcTrace", "1", CVAR_INTEGER, "used to set whether to print all actionscript traces to the console " ); int idSWF::mouseX = -1; int idSWF::mouseY = -1; @@ -516,7 +517,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, shortcutKeys = idSWFScriptObject::Alloc(); scriptFunction_shortcutKeys_clear.Bind( this ); scriptFunction_shortcutKeys_clear.Call( shortcutKeys, idSWFParmList() ); - globals->Set( "shortcutKeys", shortcutKeys ); + globals->Set( "shortcutKeys", idSWFScriptVar( shortcutKeys ) ); SWF_NATIVE_API_OBJECT_DECLARE( shortcutKeys ); globals->Set( "deactivate", scriptFunction_deactivate.Bind( this ) ); @@ -1186,8 +1187,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_shortcutKeys_clear::Call( idSWFScriptO object->Set( "UPARROW", "UP" ); object->Set( "DOWNARROW", "DOWN" ); - - return idSWFScriptVar(); + return "undefined"; } idSWFScriptVar idSWF::idSWFScriptNativeVar_blackbars::Get( idSWFScriptObject* object ) @@ -1212,9 +1212,12 @@ void idSWF::idSWFScriptNativeVar_crop::Set( idSWFScriptObject* object, const idS idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) { - common->Printf( "^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", - parms[0].ToString().c_str() ); - return idSWFScriptVar(); + if( swf_enableAbcTrace.GetBool() ) + { + common->Printf( "^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", + parms[0].ToString().c_str() ); + } + return "undefined"; } idSWFScriptVar idSWF::idSWFScriptFunction_ArrayToString::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) @@ -1236,7 +1239,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_registerUserMouse::Call( idSWFScriptOb { common->Printf( "^1 registerUserMouse \n" ); - return idSWFScriptVar(); + return "undefined"; } diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index 510ceabfa5..36a158f631 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -306,18 +306,19 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, assert( methodInfo->body ); auto* body = methodInfo->body; registers[0].SetObject( thisObject ); - idSWFBitStream abcStream( methodInfo->body->code.Ptr( ), methodInfo->body->codeLength, false ); + idSWFBitStream abcStream( body->code.Ptr( ), body->codeLength, false ); retVal = RunAbc( thisObject, stack, abcStream ); - locals->Release( ); - locals = NULL; - return retVal; + + //-- FIXME + //-- Although some of the abc bytecode is skipped, scopes should match! + //assert(scope.Num() == scopeSize + 1); } else { retVal = Run( thisObject, stack, bitstream ); + assert( scope.Num() == scopeSize + 1 ); } - assert( scope.Num() == scopeSize + 1 ); for( int i = scopeSize; i < scope.Num(); i++ ) { if( verify( scope[i] ) ) diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 217728f57d..007f06f1f6 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -72,12 +72,6 @@ void idSWFSpriteInstance::Init( idSWFSprite* _sprite, idSWFSpriteInstance* _pare sprite = _sprite; parent = _parent; depth = _depth; - swfMethod_info* method = nullptr; - - if( actionScript && actionScript->GetMethodInfo() ) - { - method = actionScript->GetMethodInfo( ); - } frameCount = sprite->frameCount; @@ -401,11 +395,14 @@ bool idSWFSpriteInstance::RunActions() { //common->DPrintf( "Calling constructor for %s%\n", name.c_str() ); idSWFScriptVar instanceInit = scriptObject->Get( "__constructor__" ); - if( !( ( idSWFScriptFunction_Script* )instanceInit.GetFunction() )->GetScope()->Num() ) + idSWFScriptFunction_Script* constructor = ( idSWFScriptFunction_Script* )instanceInit.GetFunction(); + if( !actionScript->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* )instanceInit.GetFunction() )->SetScope( *actionScript->GetScope() ); + actionScript->GetScope()->Alloc() = sprite->swf->globals; } - instanceInit.GetFunction()->Call( scriptObject, idSWFParmList() ); + actionScript->SetData( constructor->GetMethodInfo() ); + actionScript->SetAbcFile( abcFile ); + actionScript->Call( scriptObject, idSWFParmList() ); constructed = true; } } @@ -446,11 +443,12 @@ bool idSWFSpriteInstance::RunActions() idSWFParmList parms; parms.Append( eventArg ); - if( !( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Num() ) - { - ( ( idSWFScriptFunction_Script* )var.GetFunction() )->GetScope()->Append( sprite->swf->globals ); - } - var.GetFunction()->Call( scriptObject, parms ); + + idSWFScriptFunction_Script* eventFunc = ( idSWFScriptFunction_Script* )var.GetFunction(); + + actionScript->SetData( eventFunc->GetMethodInfo() ); + actionScript->SetAbcFile( abcFile ); + actionScript->Call( scriptObject, parms ); parms.Clear(); } } @@ -470,7 +468,8 @@ bool idSWFSpriteInstance::RunActions() for( int i = 0; i < functionActions.Num(); i++ ) { - functionActions[i]->Call( scriptObject, idSWFParmList() ); + actionScript->SetData( ( ( idSWFScriptFunction_Script* )functionActions[i] )->GetMethodInfo() ); + actionScript->Call( scriptObject, idSWFParmList() ); } functionActions.SetNum( 0 ); @@ -614,7 +613,6 @@ void idSWFSpriteInstance::RunTo( int targetFrame ) } DoAction( funcPtr ); } - } currentFrame = targetFrame; From fb6a8c364cd17dec4f297102942a9903d9109f7c Mon Sep 17 00:00:00 2001 From: HarrievG Date: Tue, 7 Mar 2023 01:07:40 +0100 Subject: [PATCH 10/20] - inital support for SWF entity Gui's --- neo/swf/SWF_Interpreter.cpp | 9 +++++++++ neo/swf/SWF_Main.cpp | 6 +++--- neo/ui/UserInterface.cpp | 29 +++++++++++++++++++++-------- neo/ui/Window.cpp | 28 +++++++++++++++++++++++++++- neo/ui/Window.h | 2 ++ 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index e2da5be6f7..9e6f8fe159 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -419,6 +419,11 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st idSWFScriptVar& item = stack.A(); if( item.IsFunction() ) { + auto func = ( ( idSWFScriptFunction_Script* )item.GetFunction() ); + if( !func->GetScope()->Num() ) + { + func->SetScope( *GetScope() ); + } item.GetFunction()->Call( registers[0].GetObject(), parms ); } else if( item.IsObject() ) @@ -426,6 +431,10 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st auto func = item.GetObject()->Get( funcName->c_str() ); if( func.IsFunction() ) { + if( !( ( idSWFScriptFunction_Script* )func.GetFunction() )->GetScope()->Num() ) + { + ( ( idSWFScriptFunction_Script* )func.GetFunction() )->SetScope( *GetScope() ); + } func.GetFunction()->Call( item.GetObject(), parms ); } } diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 72a6da22d6..91a0afb81c 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -1187,7 +1187,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_shortcutKeys_clear::Call( idSWFScriptO object->Set( "UPARROW", "UP" ); object->Set( "DOWNARROW", "DOWN" ); - return "undefined"; + return idSWFScriptVar(); } idSWFScriptVar idSWF::idSWFScriptNativeVar_blackbars::Get( idSWFScriptObject* object ) @@ -1217,7 +1217,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_trace::Call( idSWFScriptObject* thisOb common->Printf( "^1 [%s] ^8 % s\n", thisObject->GetSprite() ? thisObject->GetSprite()->name.c_str() : "NONAME", parms[0].ToString().c_str() ); } - return "undefined"; + return idSWFScriptVar(); } idSWFScriptVar idSWF::idSWFScriptFunction_ArrayToString::Call( idSWFScriptObject* thisObject, const idSWFParmList& parms ) @@ -1239,7 +1239,7 @@ idSWFScriptVar idSWF::idSWFScriptFunction_registerUserMouse::Call( idSWFScriptOb { common->Printf( "^1 registerUserMouse \n" ); - return "undefined"; + return idSWFScriptVar(); } diff --git a/neo/ui/UserInterface.cpp b/neo/ui/UserInterface.cpp index 8c940fc3ef..7c60b4c856 100644 --- a/neo/ui/UserInterface.cpp +++ b/neo/ui/UserInterface.cpp @@ -455,14 +455,26 @@ bool idUserInterfaceLocal::InitFromFile( const char* qpath, bool rebuild, bool c else { desktop->SetFlag( WIN_DESKTOP ); - desktop->name = "Desktop"; - desktop->text = va( "Invalid GUI: %s", qpath ); - desktop->rect = idRectangle( 0.0f, 0.0f, 640.0f, 480.0f ); - desktop->drawRect = desktop->rect; - desktop->foreColor = idVec4( 1.0f, 1.0f, 1.0f, 1.0f ); - desktop->backColor = idVec4( 0.0f, 0.0f, 0.0f, 1.0f ); + desktop->swf = new( TAG_OLD_UI )idSWF( qpath ); + + if( !desktop->swf->IsLoaded() ) + { + desktop->name = "Desktop"; + desktop->text = va( "Invalid GUI: %s", qpath ); + desktop->rect = idRectangle( 0.0f, 0.0f, 640.0f, 480.0f ); + desktop->foreColor = idVec4( 1.0f, 1.0f, 1.0f, 1.0f ); + desktop->backColor = idVec4( 0.0f, 0.0f, 0.0f, 1.0f ); + common->Warning( "Couldn't load gui: '%s'", source.c_str() ); + } + else + { + desktop->rect = idRectangle( 0.0f, 0.0f, desktop->swf->GetFrameWidth(), desktop->swf->GetFrameHeight() ); + desktop->name = desktop->swf->GetName(); + common->Warning( "loaded SWF gui: '%s'", source.c_str() ); + } + desktop->SetupFromState(); - common->Warning( "Couldn't load gui: '%s'", source.c_str() ); + } interactive = desktop->Interactive(); @@ -537,8 +549,9 @@ void idUserInterfaceLocal::DrawCursor() { dc->DrawCursor( &cursorX, &cursorY, 32.0f ); } - else + else if( !desktop->swf ) { + dc->DrawCursor( &cursorX, &cursorY, 56.0f ); } } diff --git a/neo/ui/Window.cpp b/neo/ui/Window.cpp index 50cf8d49aa..390a7a9cee 100644 --- a/neo/ui/Window.cpp +++ b/neo/ui/Window.cpp @@ -149,7 +149,7 @@ void idWindow::CommonInit() timeLine = -1; textShadow = 0; hover = false; - + swf = NULL; for( int i = 0; i < SCRIPT_COUNT; i++ ) { scripts[i] = NULL; @@ -262,6 +262,12 @@ void idWindow::CleanUp() { delete scripts[i]; } + + if( swf != NULL ) + { + delete swf; + } + CommonInit(); } @@ -799,6 +805,12 @@ const char* idWindow::HandleEvent( const sysEvent_t* event, bool* updateVisuals { dc->SetCursor( idDeviceContext::CURSOR_ARROW ); } + + if( swf && swf->IsLoaded() ) + { + swf->HandleEvent( event ); + } + } if( visible && !noEvents ) @@ -1513,6 +1525,16 @@ void idWindow::Redraw( float x, float y, bool hud ) } } + if( swf != NULL ) + { + if( !swf->IsActive() ) + { + swf->Activate( true ); + } + + swf->Render( renderSystem, Sys_Milliseconds() ); + } + // Put transforms back to what they were before the children were processed dc->SetTransformInfo( oldOrg, oldTrans ); @@ -4276,6 +4298,10 @@ idWindow::Interactive */ bool idWindow::Interactive() { + if( swf != NULL ) + { + return true;// return swf->isMouseInClientArea; + } if( scripts[ ON_ACTION ] ) { return true; diff --git a/neo/ui/Window.h b/neo/ui/Window.h index 67b830d172..3d6231a8e0 100644 --- a/neo/ui/Window.h +++ b/neo/ui/Window.h @@ -482,6 +482,8 @@ class idWindow idRegisterList regList; idWinBool hideCursor; + + idSWF* swf; }; ID_INLINE void idWindow::AddDefinedVar( idWinVar* var ) From f52defd6ead383b7a22746bd918251c5664b53a0 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Sat, 11 Mar 2023 15:09:41 +0100 Subject: [PATCH 11/20] + Fix for edit text construction in as3.0 --- neo/swf/SWF_SpriteInstance.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 007f06f1f6..a002744831 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -238,7 +238,6 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte else if( dictEntry->type == SWF_DICT_EDITTEXT ) { display.textInstance = sprite->swf->textInstanceAllocator.Alloc(); - display.textInstance->Init( dictEntry->edittext, sprite->GetSWF() ); if( dictEntry->scriptClass.IsValid( ) ) { @@ -248,12 +247,10 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte { display.textInstance->scriptObject.DeepCopy( dcopy.GetObject() ); } - super->SetPrototype( display.spriteInstance->scriptObject->GetPrototype() ); - display.spriteInstance->scriptObject->SetPrototype( super ); + super->SetPrototype( display.textInstance->scriptObject.GetPrototype() ); } - - //display.textInstance->scriptObject.Set( "onPress", "a" ); + display.textInstance->Init( dictEntry->edittext, sprite->GetSWF() ); } else if( dictEntry->type == SWF_DICT_TEXT ) { From 18e8486eedbefde2a3d19d6c80cedb8ec4c581c1 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Sat, 11 Mar 2023 15:42:01 +0100 Subject: [PATCH 12/20] fixed merge error --- neo/swf/SWF_SpriteInstance.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index a002744831..9a2fc7fa28 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -247,7 +247,8 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte { display.textInstance->scriptObject.DeepCopy( dcopy.GetObject() ); } - super->SetPrototype( display.textInstance->scriptObject.GetPrototype() ); + + display.textInstance->scriptObject.SetPrototype( super ); } display.textInstance->Init( dictEntry->edittext, sprite->GetSWF() ); From 39393a5db7f2e0bc6200e45a6a1a2eac5a660617 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Tue, 25 Apr 2023 23:57:28 +0200 Subject: [PATCH 13/20] - Crashfix for when loading an bswf with no abcTagdata - Removed redundant forward declare --- neo/swf/SWF_Load.cpp | 5 ++++- neo/swf/SWF_ShapeParser.h | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 2905fb04a9..5ccd8cefd8 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -634,7 +634,10 @@ bool idSWF::LoadBinary( const char* bfilename, ID_TIME_T sourceTimeStamp ) f->ReadString( symbolClasses.symbols[i].name ); } - DoABC( abcFile.AbcTagData ); + if ( abcFile.AbcTagData.Length() ) + { + DoABC( abcFile.AbcTagData ); + } } delete f; diff --git a/neo/swf/SWF_ShapeParser.h b/neo/swf/SWF_ShapeParser.h index 71da92f415..8f7eb01e4d 100644 --- a/neo/swf/SWF_ShapeParser.h +++ b/neo/swf/SWF_ShapeParser.h @@ -36,7 +36,6 @@ This class handles parsing and triangulating a shape class idSWFShapeParser { public: - struct swfSPDrawLine_t; idSWFShapeParser() { } void Parse( idSWFBitStream& bitstream, idSWFShape& shape, int recordType ); void ParseMorph( idSWFBitStream& bitstream, idSWFShape& shape ); From 9b1a7f97013f95839c43b4d70b0595b214a27e15 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 25 May 2023 20:59:14 +0200 Subject: [PATCH 14/20] Astyle --- neo/d3xp/menus/MenuHandler_Shell.cpp | 2 +- neo/swf/SWF_Load.cpp | 4 ++-- neo/swf/SWF_SpriteInstance.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/neo/d3xp/menus/MenuHandler_Shell.cpp b/neo/d3xp/menus/MenuHandler_Shell.cpp index d26a451e90..e4579befaa 100644 --- a/neo/d3xp/menus/MenuHandler_Shell.cpp +++ b/neo/d3xp/menus/MenuHandler_Shell.cpp @@ -60,7 +60,7 @@ void idMenuHandler_Shell::Update() ClearWidgetActionRepeater(); } - if( nextState != state && gui->IsContructed()) + if( nextState != state && gui->IsContructed() ) { if( introGui != NULL && introGui->IsActive() ) diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 5ccd8cefd8..997dac6e1c 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -634,8 +634,8 @@ bool idSWF::LoadBinary( const char* bfilename, ID_TIME_T sourceTimeStamp ) f->ReadString( symbolClasses.symbols[i].name ); } - if ( abcFile.AbcTagData.Length() ) - { + if( abcFile.AbcTagData.Length() ) + { DoABC( abcFile.AbcTagData ); } } diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 9a2fc7fa28..90433c2294 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -247,7 +247,7 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte { display.textInstance->scriptObject.DeepCopy( dcopy.GetObject() ); } - + display.textInstance->scriptObject.SetPrototype( super ); } From 57030f693a1a935803a5b97d7f8eb4879a47170b Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Tue, 27 Feb 2024 21:23:24 +0100 Subject: [PATCH 15/20] Updated copyright notices for the new Flash AS 3.0 code --- neo/swf/SWF.h | 1 + neo/swf/SWF_Abc.cpp | 23 +++++++++++++++++++++-- neo/swf/SWF_Abc.h | 27 +++++++++++++++++++++++++++ neo/swf/SWF_Bitstream.cpp | 1 + neo/swf/SWF_Bitstream.h | 1 + neo/swf/SWF_Dictionary.cpp | 1 + neo/swf/SWF_Enums.h | 1 + neo/swf/SWF_EventDispatcher.cpp | 23 +++++++++++++++++++++-- neo/swf/SWF_EventDispatcher.h | 2 +- neo/swf/SWF_Events.cpp | 5 +---- neo/swf/SWF_Interpreter.cpp | 27 +++++++++++++++++++++++++++ neo/swf/SWF_Load.cpp | 1 + neo/swf/SWF_PlaceObject.cpp | 7 +++++++ neo/swf/SWF_ScriptFunction.h | 1 + neo/swf/SWF_ScriptVar.cpp | 1 + neo/swf/SWF_ScriptVar.h | 1 + neo/swf/SWF_ShapeParser.cpp | 4 +++- neo/swf/SWF_ShapeParser.h | 3 ++- neo/swf/SWF_SpriteInstance.cpp | 6 ++++-- neo/swf/SWF_SpriteInstance.h | 1 + neo/swf/SWF_TextInstance.cpp | 4 +++- neo/swf/SWF_TextInstance.h | 1 + neo/swf/SWF_Types.h | 4 ++++ 23 files changed, 132 insertions(+), 14 deletions(-) diff --git a/neo/swf/SWF.h b/neo/swf/SWF.h index 4605196ff6..bb53487c55 100644 --- a/neo/swf/SWF.h +++ b/neo/swf/SWF.h @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2013 Robert Beckebans +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index 48649bbe27..d0d97fdf1b 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -1,8 +1,27 @@ - /* =========================================================================== -Copyright (C) 2022 HvanGinneken +Doom 3 BFG Edition GPL Source Code +Copyright (C) 2023 Harrie van Ginneken + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +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. + +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. =========================================================================== */ diff --git a/neo/swf/SWF_Abc.h b/neo/swf/SWF_Abc.h index c94dda07e6..e12e2a8cd6 100644 --- a/neo/swf/SWF_Abc.h +++ b/neo/swf/SWF_Abc.h @@ -1,3 +1,30 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 2023 Harrie van Ginneken + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +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. + +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. + +=========================================================================== +*/ #pragma once #include "SWF_Enums.h" diff --git a/neo/swf/SWF_Bitstream.cpp b/neo/swf/SWF_Bitstream.cpp index b3b2f32906..73efb0f0ab 100644 --- a/neo/swf/SWF_Bitstream.cpp +++ b/neo/swf/SWF_Bitstream.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index b823c748c8..920e245bff 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Dictionary.cpp b/neo/swf/SWF_Dictionary.cpp index 724d1717e3..f5b4415996 100644 --- a/neo/swf/SWF_Dictionary.cpp +++ b/neo/swf/SWF_Dictionary.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Enums.h b/neo/swf/SWF_Enums.h index 15d45db42d..3b964da5b0 100644 --- a/neo/swf/SWF_Enums.h +++ b/neo/swf/SWF_Enums.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_EventDispatcher.cpp b/neo/swf/SWF_EventDispatcher.cpp index e5c6aa9933..aa7d1c1486 100644 --- a/neo/swf/SWF_EventDispatcher.cpp +++ b/neo/swf/SWF_EventDispatcher.cpp @@ -1,8 +1,27 @@ - /* =========================================================================== -Copyright (C) 2022 HvanGinneken +Doom 3 BFG Edition GPL Source Code +Copyright (C) 2023 Harrie van Ginneken + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +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. + +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. =========================================================================== */ diff --git a/neo/swf/SWF_EventDispatcher.h b/neo/swf/SWF_EventDispatcher.h index 674cee117e..992b6f68d1 100644 --- a/neo/swf/SWF_EventDispatcher.h +++ b/neo/swf/SWF_EventDispatcher.h @@ -2,7 +2,7 @@ =========================================================================== Doom 3 BFG Edition GPL Source Code -Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 187e008101..1f568f5ee9 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2016-2017 Dustin Land +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -161,10 +162,6 @@ idSWFScriptObject* idSWF::HitTest( idSWFSpriteInstance* spriteInstance, const sw else if( entry->type == SWF_DICT_MORPH ) { // FIXME: this should be roughly the same as SWF_DICT_SHAPE - - //} else if( entry->type == SWF_DICT_TEXT ) - //{ - // FIXME: this should be roughly the same as SWF_DICT_SHAPE } else if( entry->type == SWF_DICT_EDITTEXT || entry->type == SWF_DICT_TEXT ) { diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index 9e6f8fe159..aa7d155a29 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -1,3 +1,30 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 2023 Harrie van Ginneken + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +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. + +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. + +=========================================================================== +*/ #include "precompiled.h" #pragma hdrstop diff --git a/neo/swf/SWF_Load.cpp b/neo/swf/SWF_Load.cpp index 997dac6e1c..2be81abd46 100644 --- a/neo/swf/SWF_Load.cpp +++ b/neo/swf/SWF_Load.cpp @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2013-2015 Robert Beckebans +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_PlaceObject.cpp b/neo/swf/SWF_PlaceObject.cpp index 9d56eca963..ede8ce5f96 100644 --- a/neo/swf/SWF_PlaceObject.cpp +++ b/neo/swf/SWF_PlaceObject.cpp @@ -147,6 +147,13 @@ void idSWFSpriteInstance::PlaceObject3( idSWFBitStream& bitstream ) uint64 flags2 = bitstream.ReadU8(); uint16 depth = bitstream.ReadU16(); + /* RB: TODO REVIEW - it has been removed compared to BFG edition + if( ( flags2 & PlaceFlagHasClassName ) != 0 || ( ( ( flags2 & PlaceFlagHasImage ) != 0 ) && ( ( flags1 & PlaceFlagHasCharacter ) != 0 ) ) ) + { + bitstream.ReadString(); // ignored + } + */ + int characterID = -1; if( ( flags1 & PlaceFlagHasCharacter ) != 0 ) { diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index 6ae57e3a85..d3b6c87a30 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2015 Robert Beckebans +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_ScriptVar.cpp b/neo/swf/SWF_ScriptVar.cpp index 13a4cffa10..652e7e54c2 100644 --- a/neo/swf/SWF_ScriptVar.cpp +++ b/neo/swf/SWF_ScriptVar.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_ScriptVar.h b/neo/swf/SWF_ScriptVar.h index f578fdbbf2..0fe1f9b654 100644 --- a/neo/swf/SWF_ScriptVar.h +++ b/neo/swf/SWF_ScriptVar.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_ShapeParser.cpp b/neo/swf/SWF_ShapeParser.cpp index 96f1177c71..e896d99f0b 100644 --- a/neo/swf/SWF_ShapeParser.cpp +++ b/neo/swf/SWF_ShapeParser.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -31,9 +32,9 @@ If you have questions concerning this license or the applicable additional terms #pragma warning( disable: 4189 ) // local variable is initialized but not referenced +// HarrievG begin void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool end ) { - //figure out what the orientation of the cap is. idVec2 up = ( verts[edge.start.v0] - verts[edge.start.v1] ); @@ -246,6 +247,7 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int } } } +// HarrievG end /* ======================== diff --git a/neo/swf/SWF_ShapeParser.h b/neo/swf/SWF_ShapeParser.h index 8f7eb01e4d..1146881620 100644 --- a/neo/swf/SWF_ShapeParser.h +++ b/neo/swf/SWF_ShapeParser.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -89,7 +90,7 @@ class idSWFShapeParser void TriangulateSoup( idSWFFontGlyph& shape ); int FindEarVert( const swfSPLineLoop_t& loop ); void AddUniqueVert( idSWFShapeDrawFill& drawFill, const idVec2& start, const idVec2& end ); - void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool end ); + void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool end ); // HarrievG }; #endif // !__SWF_SHAPEPARSER_H__ diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 90433c2294..9c4a967c76 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -133,11 +134,11 @@ void idSWFSpriteInstance::FreeDisplayList() { for( int i = 0; i < displayList.Num(); i++ ) { - if( displayList[i].spriteInstance ) { sprite->swf->spriteInstanceAllocator.Free( displayList[i].spriteInstance ); } + if( displayList[i].textInstance ) { sprite->swf->textInstanceAllocator.Free( displayList[i].textInstance ); @@ -1670,7 +1671,8 @@ SWF_SPRITE_NATIVE_VAR_DEFINE_GET( _name ) SWF_SPRITE_PTHIS_GET( "_name" ); return pThis->name.c_str(); } -//Im not sure how much of the 'legacy' underscore prefixed functions need to be changed for as3.0. + +// HarrievG: I'm not sure how much of the 'legacy' underscore prefixed functions need to be changed for as3.0. //if more is needed, we should change the macro to work for both legacy AS and 3.0 SWF_SPRITE_NATIVE_VAR_DEFINE_GET( name ) { diff --git a/neo/swf/SWF_SpriteInstance.h b/neo/swf/SWF_SpriteInstance.h index e14b60924e..123c04d614 100644 --- a/neo/swf/SWF_SpriteInstance.h +++ b/neo/swf/SWF_SpriteInstance.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_TextInstance.cpp b/neo/swf/SWF_TextInstance.cpp index 836d2f46de..f8379458a3 100644 --- a/neo/swf/SWF_TextInstance.cpp +++ b/neo/swf/SWF_TextInstance.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -68,6 +69,7 @@ idSWFTextInstance::~idSWFTextInstance() subtitleTimingInfo.Clear(); } +// HarrievG begin void idSWFTextInstance::Init( idSWFText* _text, idSWF* _swf ) { editText = nullptr; @@ -139,8 +141,8 @@ void idSWFTextInstance::Init( idSWFText* _text, idSWF* _swf ) scriptObject.SetPrototype( &textInstanceScriptObjectPrototype ); scriptObject.SetText( this ); scriptObject.SetNoAutoDelete( true ); - } +// HarrievG end /* ======================== diff --git a/neo/swf/SWF_TextInstance.h b/neo/swf/SWF_TextInstance.h index d2660e97fd..5257431fe9 100644 --- a/neo/swf/SWF_TextInstance.h +++ b/neo/swf/SWF_TextInstance.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/swf/SWF_Types.h b/neo/swf/SWF_Types.h index c291cab3e1..0485f165e1 100644 --- a/neo/swf/SWF_Types.h +++ b/neo/swf/SWF_Types.h @@ -4,6 +4,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2013-2015 Robert Beckebans +Copyright (C) 2023 Harrie van Ginneken This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -162,9 +163,12 @@ struct swfLineStyle_t uint16 endWidth; swfColorRGBA_t startColor; swfColorRGBA_t endColor; + + // HarrievG begin uint8 startCapStyle; uint8 endCapStyle; enum capStyle { round = 0, none, square }; + // HarrievG end }; struct swfGradientRecord_t { From 3dc681375033aa1e3efcc9ab1e910a1b8d904035 Mon Sep 17 00:00:00 2001 From: HarrievG Date: Wed, 19 Jul 2023 01:34:46 +0200 Subject: [PATCH 16/20] fixed swf line drawing --- neo/swf/SWF_Render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/swf/SWF_Render.cpp b/neo/swf/SWF_Render.cpp index a7865ee842..5bc8debf95 100644 --- a/neo/swf/SWF_Render.cpp +++ b/neo/swf/SWF_Render.cpp @@ -834,7 +834,7 @@ void idSWF::RenderShape( idRenderSystem* gui, const idSWFShape* shape, const swf uint32 packedColorM = LittleLong( PackColor( color.mul ) ); uint32 packedColorA = LittleLong( PackColor( ( color.add * 0.5f ) + idVec4( 0.5f ) ) ); // Compress from -1..1 to 0..1 - gui->SetGLState( GLStateForRenderState( renderState ) | GLS_POLYMODE_LINE ); + gui->SetGLState( GLStateForRenderState( renderState ) ); idDrawVert* verts = gui->AllocTris( line.startVerts.Num(), line.indices.Ptr(), line.indices.Num(), white, renderState.stereoDepth ); if( verts == NULL ) From 169d973241372cfa68e5bf530abb57a3ec4a0e3d Mon Sep 17 00:00:00 2001 From: HarrievG Date: Wed, 26 Jul 2023 20:54:34 +0200 Subject: [PATCH 17/20] Fixed swf line drawing. Please note: Only supporting round joints and caps, like < SWF 8 --- neo/swf/SWF_ShapeParser.cpp | 169 ++++++++++++++++++++++++------------ neo/swf/SWF_ShapeParser.h | 2 +- 2 files changed, 116 insertions(+), 55 deletions(-) diff --git a/neo/swf/SWF_ShapeParser.cpp b/neo/swf/SWF_ShapeParser.cpp index e896d99f0b..a0d718396a 100644 --- a/neo/swf/SWF_ShapeParser.cpp +++ b/neo/swf/SWF_ShapeParser.cpp @@ -33,26 +33,43 @@ If you have questions concerning this license or the applicable additional terms #pragma warning( disable: 4189 ) // local variable is initialized but not referenced // HarrievG begin -void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool end ) +void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld, swfSPMorphEdge_t& edge, bool start ) { //figure out what the orientation of the cap is. + uint16 v0StartIndex = edge.start.v0; + uint16 v1StartIndex = ( edge.start.cp == 0xFFFF ) ? edge.start.v1 : edge.start.cp; - idVec2 up = ( verts[edge.start.v0] - verts[edge.start.v1] ); - idVec2 down = ( verts[edge.end.v1] - verts[edge.end.v0] ); + uint16 v0EndIndex = ( edge.end.cp == 0xFFFF ) ? edge.end.v0 : edge.end.cp; + uint16 v1EndIndex = edge.end.v1; + + uint16 v0 = v0StartIndex; + uint16 v1 = v1StartIndex; + + if( !start ) + { + v0 = v0EndIndex; + v1 = v1EndIndex; + } + + idVec2 up = ( verts[v0] - verts[v1] ); + idVec2 down = ( verts[v1] - verts[v0] ); idVec2 cross = idVec2( down.y, -down.x ); idVec2 crossUp = idVec2( up.y, -up.x ); uint8 vertIndex; - if( end ) + if( !start ) { - vertIndex = edge.start.v1; + vertIndex = v1; } else { - vertIndex = edge.start.v0; + vertIndex = v0; cross = crossUp; } + float scale = ( float )( 1.0f / 20 ) * ( ld.style.startWidth * 0.5 ) ; + + //vert int capCenterIdx = ld.startVerts.AddUnique( verts[vertIndex] ); int pointCnt; float x, z; @@ -62,42 +79,28 @@ void idSWFShapeParser::MakeCap( idSWFShapeParser::swfSPDrawLine_t& spld, idSWFSh float angle = idMath::ATan( xup.y - cross.y, xup.x - cross.x ) + idMath::PI; idMath::SinCos( angle, s, c ); - float scale = ( float ) ld.style.startWidth / 40; + matrix.xx = c * scale; matrix.yx = s * scale; matrix.xy = -s * scale; matrix.yy = c * scale; int A, B; - for( float w = 0.0; w <= 180 ; w += 10 ) + for( float w = -10; w <= 180 + 10; w += 10 ) { - - if( !w ) - { - idMath::SinCos( DEG2RAD( w ), z, x ); - } - else - { - idMath::SinCos( DEG2RAD( w ), z, x ); - } + idMath::SinCos( DEG2RAD( w ), z, x ); ld.indices.Append( capCenterIdx ); A = ld.startVerts.AddUnique( matrix.Transform( idVec2( x, z ) ) + ld.startVerts[capCenterIdx] ); - if( w > 10 ) + if( w >= 0.0f ) { ld.indices.Append( B ); ld.indices.Append( A ); ld.indices.Append( capCenterIdx ); - - } - else if( w + 10 <= 180 ) - { - w += 10; } ld.indices.Append( A ); - idMath::SinCos( DEG2RAD( w ), z, x ); B = ld.startVerts.AddUnique( matrix.Transform( idVec2( x , z ) ) + ld.startVerts[capCenterIdx] ); ld.indices.Append( B ); @@ -148,36 +151,55 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int for( int e = 0; e < spld.edges.Num(); e++ ) { //startcap - if( ld.style.startCapStyle == 0 && ld.style.startWidth > 60 && spld.edges.Num() ) + //only supporting round + if( ld.style.startCapStyle == 0 ) { - MakeCap( spld, ld, spld.edges[e], false ); + MakeCap( spld, ld, spld.edges[e], true ); } - //joint. - idVec2 up = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ); - idVec2 down = ( verts[ spld.edges[e].start.v1 ] - verts[ spld.edges[e].start.v0 ] ); + + uint16 v0StartIndex = spld.edges[e].start.v0; + uint16 v1StartIndex = ( spld.edges[e].start.cp == 0xFFFF ) ? spld.edges[e].start.v1 : spld.edges[e].start.cp; + + uint16 v0EndIndex = ( spld.edges[e].end.cp == 0xFFFF ) ? spld.edges[e].end.v0 : spld.edges[e].end.cp; + uint16 v1EndIndex = spld.edges[e].end.v1; + + uint16 v0 = v0StartIndex; + uint16 v1 = v1StartIndex; + + idVec2 up = ( verts[v0] - verts[v1] ); + idVec2 down = ( verts[v1] - verts[v0] ); idVec2 cross = idVec2( down.y, -down.x ); idVec2 crossUp = idVec2( up.y, -up.x ); - idVec2 offSetA = crossUp * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 20 ); - idVec2 offSetB = cross * ( ( 1.0f / down.Length() ) * ld.style.startWidth / 40 ); - int v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetB ); - int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] + offSetA + offSetB ); - ld.indices.Append( v0 ); + float scale = ( float )( 1.0f / 20 ) * ( ld.style.startWidth * 0.5 ); + + idVec2 offSetA = crossUp * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f ; + idVec2 offSetB = cross * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f; + + v0 = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] - offSetB ); + int v0x = ld.startVerts.AddUnique( verts[ spld.edges[e].start.v0 ] - offSetA ); + + //straight line if( spld.edges[e].start.cp == 0xFFFF ) { + ld.indices.Append( v0 ); ld.indices.Append( v0x ); } - int last = v0x; + // Rather then tesselating curves at run time, we do them once here by inserting a vert every 10 units // It may not wind up being 10 actual pixels when rendered because the shape may have scaling applied to it if( spld.edges[e].start.cp != 0xFFFF ) { assert( spld.edges[e].end.cp != 0xFFFF ); - float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length(); - float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length(); + float length1 = ( verts[ spld.edges[e].start.v0 ] - verts[ spld.edges[e].start.v1 ] ).Length() * scale; + float length2 = ( verts[ spld.edges[e].end.v0 ] - verts[ spld.edges[e].end.v1 ] ).Length() * scale; int numPoints = 1 + idMath::Ftoi( Max( length1, length2 ) / 10.0f ); int lastV1; - int lastV2; + int last; + v0 = ld.startVerts.AddUnique( verts[spld.edges[e].end.v0] + offSetB ); + v0x = ld.startVerts.AddUnique( verts[spld.edges[e].end.v0] + offSetA ); + ld.indices.Append( v0 ); + for( int ti = 0; ti < numPoints; ti++ ) { float t0 = ( ti + 1 ) / ( ( float ) numPoints + 1.0f ); @@ -204,11 +226,11 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int idVec2 idown = p2 - p1; idVec2 icross = idVec2( idown.y, -idown.x ); idVec2 icrossUp = idVec2( iup.y, -iup.x ); - idVec2 ioffSetA = icrossUp * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 20 ); - idVec2 ioffSetB = icross * ( ( 1.0f / idown.Length( ) ) * ld.style.startWidth / 40 ); + idVec2 ioffSetA = icrossUp * ( ( ( 1.0f / 20 ) / idown.Length() ) * ld.style.startWidth ) * 0.5f; + idVec2 ioffSetB = icross * ( ( ( 1.0f / 20 ) / idown.Length() ) * ld.style.startWidth ) * 0.5f; - int v1 = ld.startVerts.AddUnique( p1 + ioffSetB ) ; - int v2 = ld.startVerts.AddUnique( p1 + ioffSetA + ioffSetB ) ; + v1 = ld.startVerts.AddUnique( p1 + ioffSetB ); + int v2 = ld.startVerts.AddUnique( p1 + ioffSetA ); if( ti > 0 ) { @@ -216,33 +238,72 @@ void idSWFShapeParser::Parse( idSWFBitStream& bitstream, idSWFShape& shape, int ld.indices.Append( lastV1 ); } - if( ti == 0 ) - { - ld.indices.Append( v2 ); - } ld.indices.Append( v1 ); ld.indices.Append( v2 ); if( ti > 0 ) { ld.indices.Append( v2 ); + ld.indices.Append( v1 ); + } + else + { + ld.indices.Append( v2 ); + } + + if( ti == numPoints - 1 ) + { + ld.indices.Append( v2 ); + } + + if( ti == 0 ) + { + + ld.indices.Append( v0 ); + ld.indices.Append( v0x ); + ld.indices.Append( v1 ); + ld.indices.Append( v2 ); } - ld.indices.Append( v1 ); - lastV2 = v2; lastV1 = v1; last = v2; } + + v0 = v0EndIndex; + v1 = v1EndIndex; + + up = ( verts[v0] - verts[v1] ); + down = ( verts[v1] - verts[v0] ); + cross = idVec2( down.y, -down.x ); + crossUp = idVec2( up.y, -up.x ); + + offSetA = crossUp * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f; + offSetB = cross * ( ( ( 1.0f / 20 ) / down.Length() ) * ld.style.startWidth ) * 0.5f; + + + ld.indices.Append( lastV1 ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetA ) ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetB ) ); + + ld.indices.Append( last ); + ld.indices.Append( lastV1 ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] + offSetA ) ); } - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) ); - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetA + offSetB ) ); - ld.indices.Append( last ); - ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].start.v1] + offSetB ) ); + else + { + //straight line + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetB ) ); + + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetA ) ); + ld.indices.Append( v0x ); + ld.indices.Append( ld.startVerts.AddUnique( verts[spld.edges[e].end.v1] - offSetB ) ); + } + last = ld.indices.Num() - 1; //endcap - if( ld.style.endCapStyle == 0 && ld.style.startWidth > 60 ) + if( ld.style.endCapStyle == 0 ) { - MakeCap( spld, ld, spld.edges[e], true ); + MakeCap( spld, ld, spld.edges[e], false ); } } } diff --git a/neo/swf/SWF_ShapeParser.h b/neo/swf/SWF_ShapeParser.h index 1146881620..6a11d5090a 100644 --- a/neo/swf/SWF_ShapeParser.h +++ b/neo/swf/SWF_ShapeParser.h @@ -90,7 +90,7 @@ class idSWFShapeParser void TriangulateSoup( idSWFFontGlyph& shape ); int FindEarVert( const swfSPLineLoop_t& loop ); void AddUniqueVert( idSWFShapeDrawFill& drawFill, const idVec2& start, const idVec2& end ); - void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool end ); // HarrievG + void MakeCap( swfSPDrawLine_t& spld, idSWFShapeDrawLine& ld , swfSPMorphEdge_t& edge, bool start ); }; #endif // !__SWF_SHAPEPARSER_H__ From 355269706e1fefccb214ba8977a960a7bfeca89a Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Fri, 14 Jun 2024 22:06:22 +0200 Subject: [PATCH 18/20] Fixed clang compile problems --- neo/swf/SWF_Abc.cpp | 2 +- neo/swf/SWF_EventDispatcher.h | 4 ++-- neo/swf/SWF_Interpreter.cpp | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index d0d97fdf1b..b8ca6cbb06 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -412,7 +412,7 @@ void SWF_AbcFile::ReadTraitData( idSWFBitStream& bitstream, swfTraits_info& newT } } -struct idSWFScriptObject::swfNamedVar_t ; +//struct idSWFScriptObject::swfNamedVar_t ; template<> idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& trait, idSWFScriptObject* globals ) diff --git a/neo/swf/SWF_EventDispatcher.h b/neo/swf/SWF_EventDispatcher.h index 992b6f68d1..1d8cce05e8 100644 --- a/neo/swf/SWF_EventDispatcher.h +++ b/neo/swf/SWF_EventDispatcher.h @@ -32,7 +32,7 @@ If you have questions concerning this license or the applicable additional terms #include "SWF_ParmList.h" #include "SWF_Types.h" #include "SWF_Sprites.h" -#include "swf.h" +#include "SWF.h" #include "SWF_Abc.h" class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject @@ -61,4 +61,4 @@ class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject //object.dispatchQueue = _fEventDispatcher.dispatchQueue; }; -#endif //__SWF_EVENTDISPATCHER_H__ \ No newline at end of file +#endif //__SWF_EVENTDISPATCHER_H__ diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index aa7d155a29..bebe0e2a73 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -890,7 +890,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject //ExecWordCode( hasnext ); InlineWordCode( pushnull ) { - stack.Append( idSWFScriptVar( NULL ) ); + stack.Append( idSWFScriptVar( ( idSWFScriptObject* )( NULL ) ) ); continue; } InlineWordCode( pushundefined ) @@ -1599,11 +1599,13 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject { const AbcOpcodeInfo* info = &opcodeInfo[opCode]; common->DWarning( "^5Unhandled Opcode %s\n", info ? info->name : "Empty" ); +#ifdef _WIN32 DebugBreak(); +#endif } } } abcCallstackLevel--; return returnValue; -} \ No newline at end of file +} From e5a9bd1bf38bca091f042a98a1955a81c5df2a9a Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Wed, 10 Jul 2024 20:40:29 +0200 Subject: [PATCH 19/20] Fixed compile error from merging --- neo/ui/UserInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/ui/UserInterface.cpp b/neo/ui/UserInterface.cpp index 7c60b4c856..9af3846ebe 100644 --- a/neo/ui/UserInterface.cpp +++ b/neo/ui/UserInterface.cpp @@ -455,7 +455,7 @@ bool idUserInterfaceLocal::InitFromFile( const char* qpath, bool rebuild, bool c else { desktop->SetFlag( WIN_DESKTOP ); - desktop->swf = new( TAG_OLD_UI )idSWF( qpath ); + desktop->swf = new( TAG_OLD_UI )idSWF( qpath, NULL ); if( !desktop->swf->IsLoaded() ) { From 0480cd9af576c3464bb011c08db109cf011f5bf7 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 11 Jul 2024 21:03:42 +0200 Subject: [PATCH 20/20] ( ) -> () in neo/swf/ --- neo/swf/SWF_Abc.cpp | 158 ++++++++++++++++---------------- neo/swf/SWF_Bitstream.h | 2 +- neo/swf/SWF_Dictionary.cpp | 2 +- neo/swf/SWF_EventDispatcher.cpp | 10 +- neo/swf/SWF_EventDispatcher.h | 2 +- neo/swf/SWF_Events.cpp | 110 +++++++++++----------- neo/swf/SWF_Interpreter.cpp | 106 ++++++++++----------- neo/swf/SWF_Main.cpp | 28 +++--- neo/swf/SWF_ScriptFunction.cpp | 2 +- neo/swf/SWF_ScriptFunction.h | 2 +- neo/swf/SWF_ScriptObject.cpp | 2 +- neo/swf/SWF_SpriteInstance.cpp | 12 +-- neo/swf/SWF_TextInstance.cpp | 4 +- 13 files changed, 220 insertions(+), 220 deletions(-) diff --git a/neo/swf/SWF_Abc.cpp b/neo/swf/SWF_Abc.cpp index b8ca6cbb06..bbeccf0089 100644 --- a/neo/swf/SWF_Abc.cpp +++ b/neo/swf/SWF_Abc.cpp @@ -176,42 +176,42 @@ void SWF_AbcFile::traceConstantPool( swfConstant_pool_info& constant_pool ) { trace( "^8[^7%i^8]\t ^7%i \n", cnt++, t ); } - trace( "^8uIntegers ^7: %i\n", constant_pool.uIntegers.Num( ) ); + trace( "^8uIntegers ^7: %i\n", constant_pool.uIntegers.Num() ); cnt = 0; for( auto& t : constant_pool.uIntegers ) { trace( "^8[^7%i^8]\t ^7%i \n", cnt++, ( int )t ); } - trace( "^8doubles ^7: %i\n", constant_pool.doubles.Num( ) ); + trace( "^8doubles ^7: %i\n", constant_pool.doubles.Num() ); cnt = 0; for( auto& t : constant_pool.doubles ) { trace( "^8[^7%i^8]\t ^7%f \n", cnt++, ( float ) t ); } - trace( "^8utf8Strings ^7: %i\n", constant_pool.utf8Strings.Num( ) ); + trace( "^8utf8Strings ^7: %i\n", constant_pool.utf8Strings.Num() ); cnt = 0; for( auto& t : constant_pool.utf8Strings ) { - trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t.c_str( ) ); + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t.c_str() ); } - trace( "^8namespaceNames ^7: %i\n", constant_pool.namespaceNames.Num( ) ); + trace( "^8namespaceNames ^7: %i\n", constant_pool.namespaceNames.Num() ); cnt = 0; for( auto& t : constant_pool.namespaceNames ) { - trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t->c_str( ) ); + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, t->c_str() ); } - trace( "^8namespaceSets ^7: %i\n", constant_pool.namespaceSets.Num( ) ); + trace( "^8namespaceSets ^7: %i\n", constant_pool.namespaceSets.Num() ); cnt = 0; for( auto& t : constant_pool.namespaceSets ) { for( auto& ts : t ) { - trace( "^8[^7%i^8]\t ^7%s \n", cnt++, ts->c_str( ) ); + trace( "^8[^7%i^8]\t ^7%s \n", cnt++, ts->c_str() ); } } - trace( "^8multinameInfos ^7: %i\n", constant_pool.multinameInfos.Num( ) ); + trace( "^8multinameInfos ^7: %i\n", constant_pool.multinameInfos.Num() ); cnt = 0; for( auto& t : constant_pool.multinameInfos ) { @@ -248,19 +248,19 @@ void ReadMultiName( idSWFBitStream& bitstream , swfMultiname& target ) break; case TypeName: - target.nameIndex = bitstream.ReadEncodedU32( ); - target.nameIndexT = bitstream.ReadEncodedU32( ); - target.indexT = bitstream.ReadEncoded( ); + target.nameIndex = bitstream.ReadEncodedU32(); + target.nameIndexT = bitstream.ReadEncodedU32(); + target.indexT = bitstream.ReadEncoded(); break; case Multiname: case MultinameA: - target.nameIndex = bitstream.ReadEncodedU32( ); - target.index = bitstream.ReadEncodedU32( ); + target.nameIndex = bitstream.ReadEncodedU32(); + target.index = bitstream.ReadEncodedU32(); break; case MultinameL: case MultinameLA: - target.index = bitstream.ReadEncodedU32( ); + target.index = bitstream.ReadEncodedU32(); break; default: common->FatalError( "Invalid Multiname type" ); @@ -271,78 +271,78 @@ void ReadMultiName( idSWFBitStream& bitstream , swfMultiname& target ) void ReadConstantPoolInfo( idSWFBitStream& bitstream , swfConstant_pool_info& target ) { /*cpool_info{}*/ - uint32 int_count = bitstream.ReadEncodedU32( ) ; - target.integers.Alloc( ) = 0; + uint32 int_count = bitstream.ReadEncodedU32() ; + target.integers.Alloc() = 0; for( uint i = 1; i < int_count; i++ ) { - target.integers.Alloc( ) = bitstream.ReadEncoded( ); + target.integers.Alloc() = bitstream.ReadEncoded(); } - uint32 uint_count = bitstream.ReadEncodedU32( ); - target.uIntegers.Alloc( ) = 0; + uint32 uint_count = bitstream.ReadEncodedU32(); + target.uIntegers.Alloc() = 0; for( uint i = 1; i < uint_count; i++ ) { - target.uIntegers.Alloc( ) = bitstream.ReadEncodedU32( ); + target.uIntegers.Alloc() = bitstream.ReadEncodedU32(); } - uint32 double_count = bitstream.ReadEncodedU32( ); - target.doubles.Alloc( ) = 0.0; + uint32 double_count = bitstream.ReadEncodedU32(); + target.doubles.Alloc() = 0.0; for( uint i = 1; i < double_count; i++ ) { //WARNING IEEE-754 target.doubles.Alloc() = *( double* )bitstream.ReadData( 8 ); } - uint32 string_count = bitstream.ReadEncodedU32( ); - target.utf8Strings.Alloc( ).Append( "*" ); + uint32 string_count = bitstream.ReadEncodedU32(); + target.utf8Strings.Alloc().Append( "*" ); for( uint i = 1; i < string_count; i++ ) { - uint32 str_len = bitstream.ReadEncodedU32( ); - target.utf8Strings.Alloc( ).Append( ( char* ) bitstream.ReadData( str_len ), str_len ); + uint32 str_len = bitstream.ReadEncodedU32(); + target.utf8Strings.Alloc().Append( ( char* ) bitstream.ReadData( str_len ), str_len ); } - uint32 namespace_count = bitstream.ReadEncodedU32( ); - target.namespaceNames.Alloc( ) = &target.utf8Strings[0]; + uint32 namespace_count = bitstream.ReadEncodedU32(); + target.namespaceNames.Alloc() = &target.utf8Strings[0]; for( uint i = 1; i < namespace_count; i++ ) { target.namespaceKinds.Alloc() = ( swfConstantKind_t )bitstream.ReadU8(); - uint32 str_idx = bitstream.ReadEncodedU32( ); - target.namespaceNames.Alloc( ) = &target.utf8Strings[( int )str_idx]; + uint32 str_idx = bitstream.ReadEncodedU32(); + target.namespaceNames.Alloc() = &target.utf8Strings[( int )str_idx]; } - uint32 namespace_set_count = bitstream.ReadEncodedU32( ); - target.namespaceSets.Alloc( ).Alloc() = target.namespaceNames[0]; + uint32 namespace_set_count = bitstream.ReadEncodedU32(); + target.namespaceSets.Alloc().Alloc() = target.namespaceNames[0]; for( uint i = 1; i < namespace_set_count; i++ ) { - uint32 count = bitstream.ReadEncodedU32( ); + uint32 count = bitstream.ReadEncodedU32(); auto& newSet = target.namespaceSets.Alloc(); for( uint j = 0; j < count; j++ ) { - uint32 idx = bitstream.ReadEncodedU32( ); + uint32 idx = bitstream.ReadEncodedU32(); newSet.Alloc() = target.namespaceNames[( int )idx]; } } - uint32 multiname_count = bitstream.ReadEncodedU32( ); - auto& empty = target.multinameInfos.Alloc( ); + uint32 multiname_count = bitstream.ReadEncodedU32(); + auto& empty = target.multinameInfos.Alloc(); empty.index = 0; empty.nameIndex = 0; empty.type = unused_0x00; for( uint i = 1; i < multiname_count; i++ ) { - auto& newMn = target.multinameInfos.Alloc( ); + auto& newMn = target.multinameInfos.Alloc(); ReadMultiName( bitstream, newMn ); } } void SWF_AbcFile::ReadOptionInfo( idSWFBitStream& bitstream, swfOption_info& newOption ) { - newOption.option_count = bitstream.ReadEncodedU32( ); + newOption.option_count = bitstream.ReadEncodedU32(); for( uint i = 0; i < newOption.option_count; i++ ) { - auto& newItem = newOption.options.Alloc( ); - newItem.val = bitstream.ReadEncodedU32( ); - newItem.kind = constant_pool.namespaceKinds[bitstream.ReadEncodedU32( )]; + auto& newItem = newOption.options.Alloc(); + newItem.val = bitstream.ReadEncodedU32(); + newItem.kind = constant_pool.namespaceKinds[bitstream.ReadEncodedU32()]; } } @@ -385,24 +385,24 @@ void SWF_AbcFile::ReadTraitData( idSWFBitStream& bitstream, swfTraits_info& newT { newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_method ), TAG_SWF ); swfTrait_method& method = *( swfTrait_method* )( newTraitsData.data ); - method.disp_id = bitstream.ReadEncodedU32( ); - method.method = &methods[bitstream.ReadEncodedU32( )]; + method.disp_id = bitstream.ReadEncodedU32(); + method.method = &methods[bitstream.ReadEncodedU32()]; } break; case swfTraits_info::Trait_Class: { newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ), TAG_SWF ); swfTrait_class& tclass = *( swfTrait_class* )( newTraitsData.data ); - tclass.slot_id = bitstream.ReadEncodedU32( ); - tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + tclass.slot_id = bitstream.ReadEncodedU32(); + tclass.classi = &classes[bitstream.ReadEncodedU32()]; } break; case swfTraits_info::Trait_Function: { newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ), TAG_SWF ); swfTrait_function& func = *( swfTrait_function* )( newTraitsData.data ); - func.slot_id = bitstream.ReadEncodedU32( ); - func.func = &methods[bitstream.ReadEncodedU32( )]; + func.slot_id = bitstream.ReadEncodedU32(); + func.func = &methods[bitstream.ReadEncodedU32()]; } break; @@ -474,7 +474,7 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t case QnameA: { idStr& typeName = constant_pool.utf8Strings[slot.vindex]; - if( globals->HasProperty( typeName.c_str( ) ) ) + if( globals->HasProperty( typeName.c_str() ) ) { newVar->value.SetObject( globals->GetObject( typeName ) ); } @@ -519,7 +519,7 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t else { idStr& typeName = constant_pool.utf8Strings[slot.type_name->nameIndex]; - if( globals->HasProperty( typeName.c_str( ) ) ) + if( globals->HasProperty( typeName.c_str() ) ) { auto* newobj = idSWFScriptObject::Alloc(); newobj->SetPrototype( globals->GetObject( typeName.c_str() ) ); @@ -556,19 +556,19 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t slashPos = owner.Find( ":" ); if( slashPos != -1 ) { - owner = idStr( owner.c_str( ), slashPos + 1, owner.Length() ); + owner = idStr( owner.c_str(), slashPos + 1, owner.Length() ); } if( globals->HasProperty( owner.c_str() ) ) { - idSWFScriptFunction_Script* func = idSWFScriptFunction_Script::Alloc( ); + idSWFScriptFunction_Script* func = idSWFScriptFunction_Script::Alloc(); func->SetAbcFile( this ); func->SetData( method.method ); newVar->value = idSWFScriptVar( func ) ; } else { - newVar->value.SetUndefined( ); + newVar->value.SetUndefined(); } break; @@ -579,8 +579,8 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t int a = 0; //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_class ) ); //swfTrait_class &tclass = *( swfTrait_class * ) ( newTraitsData.data ); - //tclass.slot_id = bitstream.ReadEncodedU32( ); - //tclass.classi = &classes[bitstream.ReadEncodedU32( )]; + //tclass.slot_id = bitstream.ReadEncodedU32(); + //tclass.classi = &classes[bitstream.ReadEncodedU32()]; } break; case swfTraits_info::Trait_Function: @@ -588,8 +588,8 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t int a = 0; //newTraitsData.data = Mem_ClearedAlloc( sizeof( swfTrait_function ) ); //swfTrait_function &func = *( swfTrait_function * ) ( newTraitsData.data ); - //func.slot_id = bitstream.ReadEncodedU32( ); - //func.func = &methods[bitstream.ReadEncodedU32( )]; + //func.slot_id = bitstream.ReadEncodedU32(); + //func.func = &methods[bitstream.ReadEncodedU32()]; } break; @@ -603,7 +603,7 @@ idSWFScriptObject::swfNamedVar_t* SWF_AbcFile::GetTrait( const swfTraits_info& t void SWF_AbcFile::ReadTraitsInfo( idSWFBitStream& bitstream, swfTraits_info& newTraitsData ) { - newTraitsData.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + newTraitsData.name = &constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; //The kind field contains two four-bit fields. The lower four bits determine the kind of this trait. The // upper four bits comprise a bit vector providing attributes of the trait. See the following tables and // sections for full descriptions. @@ -634,12 +634,12 @@ void SWF_AbcFile::ReadClassInfo( idSWFBitStream& bitstream, swfClass_info& newCl } -//The last entry in that array is the entry point for the ABC file; that is, the last entry�s -//initialization method contains the first bytecode that�s run when the ABC file is executed. +//The last entry in that array is the entry point for the ABC file; that is, the last entry�s +//initialization method contains the first bytecode that�s run when the ABC file is executed. void SWF_AbcFile::ReadScriptInfo( idSWFBitStream& bitstream, swfScript_info& newScriptData ) { - uint32 init = bitstream.ReadEncodedU32( ); - uint32 trait_count = bitstream.ReadEncodedU32( ); + uint32 init = bitstream.ReadEncodedU32(); + uint32 trait_count = bitstream.ReadEncodedU32(); newScriptData.init = &methods[init]; trace( "%s \n", newScriptData.init->name->c_str() ); newScriptData.traits.AssureSize( trait_count ); @@ -662,7 +662,7 @@ void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream& bitstream, swfMethod_body_ newMethodBody.codeLength = bitstream.ReadEncodedU32(); newMethodBody.code.Load( bitstream.ReadData( newMethodBody.codeLength ), newMethodBody.codeLength, true ); // ( byte * ) Mem_ClearedAlloc( sizeof( byte ) * newMethodBody.codeLength ); extern void swf_PrintStream( SWF_AbcFile * file , idSWFBitStream & bitstream ); - if( swf_abc_verbose.GetInteger( ) == 2 ) + if( swf_abc_verbose.GetInteger() == 2 ) { common->Printf( "============================\n" ); common->Printf( "Method %s 's bytecode \n", newMethodBody.method->name->c_str() ); @@ -670,23 +670,23 @@ void SWF_AbcFile::ReadMethodBodyInfo( idSWFBitStream& bitstream, swfMethod_body_ swf_PrintStream( this, newMethodBody.code ); } //memcpy(newMethodBody.code,bitstream.ReadData(newMethodBody.codeLength),newMethodBody.codeLength); - uint32 exception_count = bitstream.ReadEncodedU32( ); + uint32 exception_count = bitstream.ReadEncodedU32(); for( uint i = 0; i < exception_count; i++ ) { - auto& newExceptionInfo = newMethodBody.exceptions.Alloc( ); + auto& newExceptionInfo = newMethodBody.exceptions.Alloc(); ReadExceptionInfo( bitstream, newExceptionInfo ); } - uint32 trait_count = bitstream.ReadEncodedU32( ); + uint32 trait_count = bitstream.ReadEncodedU32(); for( uint i = 0; i < trait_count; i++ ) { - auto& newTrait = newMethodBody.traits.Alloc( ); + auto& newTrait = newMethodBody.traits.Alloc(); ReadTraitsInfo( bitstream, newTrait ); } } void SWF_AbcFile::ReadExceptionInfo( idSWFBitStream& bitstream, swfException_info& newException ) { - newException.from = bitstream.ReadEncodedU32( ); + newException.from = bitstream.ReadEncodedU32(); newException.to = bitstream.ReadEncodedU32(); newException.target = bitstream.ReadEncodedU32(); newException.exc_type = &constant_pool.utf8Strings[bitstream.ReadEncodedU32()]; @@ -718,7 +718,7 @@ void SWF_AbcFile::ReadInstanceInfo( idSWFBitStream& bitstream, swfInstance_info& newInstancedata.iinit = &methods[bitstream.ReadEncodedU32()]; - uint32 trait_count = bitstream.ReadEncodedU32( ); + uint32 trait_count = bitstream.ReadEncodedU32(); for( uint i = 0; i < trait_count; i++ ) { @@ -757,7 +757,7 @@ void SWF_AbcFile::ReadMethodInfo( idSWFBitStream& bitstream , swfMethod_info& ne for( uint i = 0; i < newMethod.paramCount; i++ ) { - idx = bitstream.ReadEncodedU32( ); + idx = bitstream.ReadEncodedU32(); newMethod.paramNames.Alloc() = &constant_pool.utf8Strings[idx]; trace( "newMethod.param %s \n", constant_pool.utf8Strings[idx].c_str() ); @@ -784,7 +784,7 @@ void SWF_AbcFile::LoadBinary( idFile* file ) void idSWF::DoABC( idSWFBitStream& bitstream ) { SWF_AbcFile& newAbcFile = abcFile; - int strmSize = bitstream.Length( ) + 6; // codeLength(uin16) + recordLength(uin32) + int strmSize = bitstream.Length() + 6; // codeLength(uin16) + recordLength(uin32) if( !newAbcFile.AbcTagData.Length() ) { @@ -793,8 +793,8 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) uint32 flags = bitstream.ReadU32(); idStr name = bitstream.ReadString(); - int dataSize = bitstream.Length( ) - name.Length( ); - common->Printf( "DoABC %s flags %i tagsize %i bytecode size %i \n", name.c_str( ), flags, strmSize, dataSize ); + int dataSize = bitstream.Length() - name.Length(); + common->Printf( "DoABC %s flags %i tagsize %i bytecode size %i \n", name.c_str(), flags, strmSize, dataSize ); bitstream.ReadLittle( newAbcFile.minor_version ); bitstream.ReadLittle( newAbcFile.major_version ); @@ -802,7 +802,7 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) ReadConstantPoolInfo( bitstream, newAbcFile.constant_pool ); SWF_AbcFile::traceConstantPool( newAbcFile.constant_pool ); - uint32 method_count = bitstream.ReadEncodedU32( ) ; + uint32 method_count = bitstream.ReadEncodedU32() ; newAbcFile.methods.AssureSize( method_count ); trace( "method_count %i \n", method_count ); for( uint i = 0; i < method_count; i++ ) @@ -811,7 +811,7 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) newAbcFile.ReadMethodInfo( bitstream, newMethod ); } - uint32 meta_count = bitstream.ReadEncodedU32( ); + uint32 meta_count = bitstream.ReadEncodedU32(); newAbcFile.metadatas.AssureSize( meta_count ); trace( "meta_count %i \n", meta_count ); for( uint i = 0; i < meta_count; i++ ) @@ -837,7 +837,7 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) newAbcFile.ReadClassInfo( bitstream, newClass ); } - uint32 script_count = bitstream.ReadEncodedU32( ); + uint32 script_count = bitstream.ReadEncodedU32(); newAbcFile.scripts.AssureSize( script_count ); trace( "script_count %i \n", script_count ); for( uint i = 0; i < script_count; i++ ) @@ -846,7 +846,7 @@ void idSWF::DoABC( idSWFBitStream& bitstream ) newAbcFile.ReadScriptInfo( bitstream, newScript ); } - uint32 methBody_count = bitstream.ReadEncodedU32( ); + uint32 methBody_count = bitstream.ReadEncodedU32(); newAbcFile.method_bodies.AssureSize( methBody_count ); trace( "methBody_count %i \n", methBody_count ); for( uint i = 0; i < methBody_count; i++ ) @@ -870,8 +870,8 @@ void idSWF::SymbolClass( idSWFBitStream& bitstream ) for( uint i = 0 ; i < numSymbols; i++ ) { auto& newSymbol = symbolClasses.symbols.Alloc(); - newSymbol.tag = bitstream.ReadU16( ); - newSymbol.name = bitstream.ReadString( ); + newSymbol.tag = bitstream.ReadU16(); + newSymbol.name = bitstream.ReadString(); trace( "SymbolClass ^5%i ^7tag ^5%i ^2%s \n", i, newSymbol.tag, newSymbol.name.c_str() ); } } diff --git a/neo/swf/SWF_Bitstream.h b/neo/swf/SWF_Bitstream.h index 920e245bff..e4a3333c0f 100644 --- a/neo/swf/SWF_Bitstream.h +++ b/neo/swf/SWF_Bitstream.h @@ -94,7 +94,7 @@ class idSWFBitStream T result = 0; for( int i = 0; i < 5; i++ ) { - byte b = ReadU8( ); + byte b = ReadU8(); result |= ( b & 0x7F ) << ( 7 * i ); if( ( b & 0x80 ) == 0 ) { diff --git a/neo/swf/SWF_Dictionary.cpp b/neo/swf/SWF_Dictionary.cpp index f5b4415996..d99394ba78 100644 --- a/neo/swf/SWF_Dictionary.cpp +++ b/neo/swf/SWF_Dictionary.cpp @@ -45,7 +45,7 @@ idSWFDictionaryEntry::idSWFDictionaryEntry() : imageSize( 0, 0 ), imageAtlasOffset( 0, 0 ), channelScale( 1.0f, 1.0f, 1.0f, 1.0f ), - scriptClass( ), + scriptClass(), resolved( false ), name( NULL ) { diff --git a/neo/swf/SWF_EventDispatcher.cpp b/neo/swf/SWF_EventDispatcher.cpp index aa7d1c1486..e90cd95b89 100644 --- a/neo/swf/SWF_EventDispatcher.cpp +++ b/neo/swf/SWF_EventDispatcher.cpp @@ -62,8 +62,8 @@ SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( MouseEvent ) static idSWFScriptObject* mouseEventObj = nullptr; if( mouseEventObj == nullptr ) { - mouseEventObj = idSWFScriptObject::Alloc( ); - idSWFScriptObject* eventParms = idSWFScriptObject::Alloc( ); + mouseEventObj = idSWFScriptObject::Alloc(); + idSWFScriptObject* eventParms = idSWFScriptObject::Alloc(); eventParms->Set( "type", "MouseEvent" ); mouseEventObj->Set( "[MouseEvent]", eventParms ); @@ -95,8 +95,8 @@ SWF_EVENTDISPATCHER_NATIVE_VAR_DEFINE_GET( Event ) static idSWFScriptObject* eventObj = nullptr; if( eventObj == nullptr ) { - eventObj = idSWFScriptObject::Alloc( ); - idSWFScriptObject* eventParms = idSWFScriptObject::Alloc( ); + eventObj = idSWFScriptObject::Alloc(); + idSWFScriptObject* eventParms = idSWFScriptObject::Alloc(); eventParms->Set( "type", "Event" ); eventObj->Set( "[Event]", eventParms ); @@ -176,7 +176,7 @@ SWF_EVENTDISPATCHER_FUNCTION_DEFINE( addEventListener ) dispatcher->value.GetObject()->Set( parms[0].ToString(), parms[1] ); common->DPrintf( "{%s} AddEventListener(%s,%s)\n", thisObject->GetSprite()->name.c_str(), parms[0].ToString().c_str(), parms[1].ToString().c_str() ); //add listener - return idSWFScriptVar( ); + return idSWFScriptVar(); } diff --git a/neo/swf/SWF_EventDispatcher.h b/neo/swf/SWF_EventDispatcher.h index 1d8cce05e8..38204416d9 100644 --- a/neo/swf/SWF_EventDispatcher.h +++ b/neo/swf/SWF_EventDispatcher.h @@ -38,7 +38,7 @@ If you have questions concerning this license or the applicable additional terms class idSWFScriptObject_EventDispatcherPrototype : public idSWFScriptObject { public: - idSWFScriptObject_EventDispatcherPrototype( ); + idSWFScriptObject_EventDispatcherPrototype(); #define SWF_EVENTDISPATCHER_FUNCTION_DECLARE( x ) \ class idSWFScriptFunction_##x : public idSWFScriptFunction { \ public: \ diff --git a/neo/swf/SWF_Events.cpp b/neo/swf/SWF_Events.cpp index 1f568f5ee9..3bd05f54ba 100644 --- a/neo/swf/SWF_Events.cpp +++ b/neo/swf/SWF_Events.cpp @@ -34,7 +34,7 @@ idSWFScriptObject* GetMouseEventDispatcher( idSWFScriptObject* object ) idSWFScriptObject* dispatcher = nullptr; if( object->HasValidProperty( "__eventDispatcher__" ) ) { - dispatcher = object->Get( "__eventDispatcher__" ).GetObject( ); + dispatcher = object->Get( "__eventDispatcher__" ).GetObject(); if( dispatcher->HasValidProperty( "click" ) || dispatcher->HasValidProperty( "contextMenu" ) || dispatcher->HasValidProperty( "doubleClick" ) @@ -327,34 +327,34 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) if( !eventDispatcher.IsUndefined() && !var.IsFunction() ) { - var = eventDispatcher.GetObject( )->Get( "click" ); - if( !var.IsFunction( ) ) + var = eventDispatcher.GetObject()->Get( "click" ); + if( !var.IsFunction() ) { - var = eventDispatcher.GetObject( )->Get( "mouseDown" ); + var = eventDispatcher.GetObject()->Get( "mouseDown" ); } } - if( var.IsFunction( ) ) + if( var.IsFunction() ) { idSWFScriptVar eventArg; - auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); - eventArg.SetObject( idSWFScriptObject::Alloc( ) ); - eventArg.GetObject( )->DeepCopy( eventObj ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject() + ->Get( "MouseEvent" ).GetObject() + ->Get( "[MouseEvent]" ).GetObject(); + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); parms.Append( event->inputDevice ); - if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Append( globals ); } - var.GetFunction( )->Call( hitObject, parms ); - parms.Clear( ); + var.GetFunction()->Call( hitObject, parms ); + parms.Clear(); return true; } var = hitObject->Get( "onPress" ); - if( var.IsFunction( ) ) + if( var.IsFunction() ) { idSWFParmList parms; parms.Append( event->inputDevice ); @@ -387,27 +387,27 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) { eventDispatcher = mouseObject->Get( "__eventDispatcher__" ); - if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined() && !var.IsFunction() ) { - var = eventDispatcher.GetObject( )->Get( "mouseUp" ); + var = eventDispatcher.GetObject()->Get( "mouseUp" ); } - if( var.IsFunction( ) ) + if( var.IsFunction() ) { idSWFScriptVar eventArg; - auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); - eventArg.SetObject( idSWFScriptObject::Alloc( ) ); - eventArg.GetObject( )->DeepCopy( eventObj ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject() + ->Get( "MouseEvent" ).GetObject() + ->Get( "[MouseEvent]" ).GetObject(); + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Append( globals ); } - var.GetFunction( )->Call( mouseObject, parms ); - parms.Clear( ); - mouseObject->Release( ); + var.GetFunction()->Call( mouseObject, parms ); + parms.Clear(); + mouseObject->Release(); mouseObject = NULL; return true; } @@ -608,31 +608,31 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) idSWFScriptVar var = hoverObject->Get( "onRollOut" ); eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); - if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined() && !var.IsFunction() ) { - var = eventDispatcher.GetObject( )->Get( "mouseOut" ); - if( var.IsFunction( ) ) + var = eventDispatcher.GetObject()->Get( "mouseOut" ); + if( var.IsFunction() ) { idSWFScriptVar eventArg; - auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); - eventArg.SetObject( idSWFScriptObject::Alloc( ) ); - eventArg.GetObject( )->DeepCopy( eventObj ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject() + ->Get( "MouseEvent" ).GetObject() + ->Get( "[MouseEvent]" ).GetObject(); + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Append( globals ); } - var.GetFunction( )->Call( hoverObject, parms ); - parms.Clear( ); + var.GetFunction()->Call( hoverObject, parms ); + parms.Clear(); retVal = true; } } - else if( var.IsFunction( ) ) + else if( var.IsFunction() ) { - var.GetFunction( )->Call( hoverObject, idSWFParmList( ) ); + var.GetFunction()->Call( hoverObject, idSWFParmList() ); retVal = true; } hoverObject->Release(); @@ -646,31 +646,31 @@ bool idSWF::HandleEvent( const sysEvent_t* event ) idSWFScriptVar var = hitObject->Get( "onRollOver" ); eventDispatcher = hoverObject->Get( "__eventDispatcher__" ); - if( !eventDispatcher.IsUndefined( ) && !var.IsFunction( ) ) + if( !eventDispatcher.IsUndefined() && !var.IsFunction() ) { - var = eventDispatcher.GetObject( )->Get( "mouseOver" ); + var = eventDispatcher.GetObject()->Get( "mouseOver" ); if( var.IsFunction() ) { idSWFScriptVar eventArg; - auto* eventObj = globals->Get( "EventDispatcher" ).GetObject( ) - ->Get( "MouseEvent" ).GetObject( ) - ->Get( "[MouseEvent]" ).GetObject( ); - eventArg.SetObject( idSWFScriptObject::Alloc( ) ); - eventArg.GetObject( )->DeepCopy( eventObj ); + auto* eventObj = globals->Get( "EventDispatcher" ).GetObject() + ->Get( "MouseEvent" ).GetObject() + ->Get( "[MouseEvent]" ).GetObject(); + eventArg.SetObject( idSWFScriptObject::Alloc() ); + eventArg.GetObject()->DeepCopy( eventObj ); idSWFParmList parms; parms.Append( eventArg ); - if( !( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Num( ) ) + if( !( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Num() ) { - ( ( idSWFScriptFunction_Script* ) var.GetFunction( ) )->GetScope( )->Append( globals ); + ( ( idSWFScriptFunction_Script* ) var.GetFunction() )->GetScope()->Append( globals ); } - var.GetFunction( )->Call( hoverObject, parms ); - parms.Clear( ); + var.GetFunction()->Call( hoverObject, parms ); + parms.Clear(); retVal = true; } } - else if( var.IsFunction( ) ) + else if( var.IsFunction() ) { - var.GetFunction( )->Call( hitObject, idSWFParmList( ) ); + var.GetFunction()->Call( hitObject, idSWFParmList() ); retVal = true; } } diff --git a/neo/swf/SWF_Interpreter.cpp b/neo/swf/SWF_Interpreter.cpp index bebe0e2a73..8f945ed41e 100644 --- a/neo/swf/SWF_Interpreter.cpp +++ b/neo/swf/SWF_Interpreter.cpp @@ -276,7 +276,7 @@ void swf_PrintStream( SWF_AbcFile* file, idSWFBitStream& bitstream ) DoWordCode( restargc ); DoWordCode( restarg ); default: - common->Printf( "default %s %s\n", type.c_str( ) , info ? info->name : "Empty" ); + common->Printf( "default %s %s\n", type.c_str() , info ? info->name : "Empty" ); } static const char* tabs[] = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; if( info && info->operandCount > 0 ) @@ -284,7 +284,7 @@ void swf_PrintStream( SWF_AbcFile* file, idSWFBitStream& bitstream ) bitstream.ReadData( info->operandCount ); } common->Printf( " %s %s o %s%i \t s %s%i \n" , - info ? info->name : type.c_str( ), + info ? info->name : type.c_str(), tabs[int( 18 - ( int( idStr::Length( info->name ) ) ) )], info->operandCount > 0 ? "^2" : "^1" , info->operandCount, @@ -328,21 +328,21 @@ void idSWFScriptFunction_Script::findproperty( SWF_AbcFile* file, idSWFStack& st void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { const auto& cp = file->constant_pool; - const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; //search up scope stack. - for( int i = scope.Num( ) - 1; i >= 0; i-- ) + for( int i = scope.Num() - 1; i >= 0; i-- ) { auto* s = scope[i]; while( s ) - if( s->HasProperty( propName->c_str( ) ) ) + if( s->HasProperty( propName->c_str() ) ) { - stack.Alloc( ) = s->Get( propName->c_str( ) ); + stack.Alloc() = s->Get( propName->c_str() ); return; } - else if( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype( ) ) + else if( s->GetPrototype() && s->GetPrototype()->GetPrototype() ) { - s = s->GetPrototype( )->GetPrototype( ); + s = s->GetPrototype()->GetPrototype(); } else { @@ -357,21 +357,21 @@ void idSWFScriptFunction_Script::findpropstrict( SWF_AbcFile* file, idSWFStack& void idSWFScriptFunction_Script::getlex( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { const auto& cp = file->constant_pool; - const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; //search up scope stack. - for( int i = scope.Num( ) - 1; i >= 0; i-- ) + for( int i = scope.Num() - 1; i >= 0; i-- ) { auto* s = scope[i]; while( s ) - if( s->HasProperty( propName->c_str( ) ) ) + if( s->HasProperty( propName->c_str() ) ) { - stack.Alloc( ) = s->Get( propName->c_str( ) ); + stack.Alloc() = s->Get( propName->c_str() ); return; } - else if( s->GetPrototype( ) && s->GetPrototype( )->GetPrototype() ) + else if( s->GetPrototype() && s->GetPrototype()->GetPrototype() ) { - s = s->GetPrototype( )->GetPrototype(); + s = s->GetPrototype()->GetPrototype(); } else { @@ -413,7 +413,7 @@ void idSWFScriptFunction_Script::getlocal0( SWF_AbcFile* file, idSWFStack& stack //Classes are constructed implicitly void idSWFScriptFunction_Script::newclass( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { - const auto& ci = file->classes[bitstream.ReadEncodedU32( )]; + const auto& ci = file->classes[bitstream.ReadEncodedU32()]; idSWFScriptVar base = stack.A(); stack.Pop( 1 ); idSWFScriptVar* thisObj = ®isters[0]; @@ -423,7 +423,7 @@ void idSWFScriptFunction_Script::newclass( SWF_AbcFile* file, idSWFStack& stack, void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& stack, idSWFBitStream& bitstream ) { const auto& cp = file->constant_pool; - const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = file->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; uint32 arg_count = bitstream.ReadEncodedU32(); @@ -436,7 +436,7 @@ void idSWFScriptFunction_Script::callpropvoid( SWF_AbcFile* file, idSWFStack& st } idSWFParmList parms( arg_count ); - for( int i = 0; i < parms.Num( ); i++ ) + for( int i = 0; i < parms.Num(); i++ ) { parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); @@ -489,7 +489,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } abcCallstackLevel++; - while( bitstream.Tell( ) < bitstream.Length( ) ) + while( bitstream.Tell() < bitstream.Length() ) { #define ExecWordCode( n ) case OP_##n: n(abcFile,stack,bitstream); continue; #define InlineWordCode( n ) case OP_##n: @@ -938,28 +938,28 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject InlineWordCode( pushstring ) { const auto& cp = abcFile->constant_pool.utf8Strings; - const auto& mn = cp[bitstream.ReadEncodedU32( )]; + const auto& mn = cp[bitstream.ReadEncodedU32()]; stack.Append( idSWFScriptString( mn ) ); continue; } InlineWordCode( pushint ) { const auto& cp = abcFile->constant_pool.integers; - const auto& val = cp[bitstream.ReadEncodedU32( )]; + const auto& val = cp[bitstream.ReadEncodedU32()]; stack.Append( idSWFScriptVar( val ) ); continue; } InlineWordCode( pushuint ) { const auto& cp = abcFile->constant_pool.uIntegers; - const auto& val = cp[bitstream.ReadEncodedU32( )]; + const auto& val = cp[bitstream.ReadEncodedU32()]; stack.Append( idSWFScriptVar( ( int )val ) ); continue; } InlineWordCode( pushdouble ) { const auto& cp = abcFile->constant_pool.doubles; - const auto& val = cp[bitstream.ReadEncodedU32( )]; + const auto& val = cp[bitstream.ReadEncodedU32()]; stack.Append( idSWFScriptVar( ( float )val ) ); continue; } @@ -1006,25 +1006,25 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject { //fold this with callpropvoid. const auto& cp = abcFile->constant_pool; - const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; const idStrPtr funcName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; - uint32 arg_count = bitstream.ReadEncodedU32( ); + uint32 arg_count = bitstream.ReadEncodedU32(); idSWFParmList parms( arg_count ); - for( int i = 0; i < parms.Num( ); i++ ) + for( int i = 0; i < parms.Num(); i++ ) { - parms[parms.Num() - 1 - i] = stack.A( ); + parms[parms.Num() - 1 - i] = stack.A(); stack.Pop( 1 ); } - idSWFScriptVar& item = stack.A( ); + idSWFScriptVar& item = stack.A(); - if( item.IsFunction( ) ) + if( item.IsFunction() ) { stack.Pop( 1 ); - stack.Alloc() = item.GetFunction( )->Call( registers[0].GetObject( ), parms ); + stack.Alloc() = item.GetFunction()->Call( registers[0].GetObject(), parms ); } - else if( item.IsObject( ) ) + else if( item.IsObject() ) { auto func = item.GetObject()->Get( funcName->c_str() ); if( !func.IsFunction() ) // search up scope @@ -1052,9 +1052,9 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } } } - if( func.IsFunction( ) ) + if( func.IsFunction() ) { - stack.Alloc() = func.GetFunction( )->Call( item.GetObject( ), parms ); + stack.Alloc() = func.GetFunction()->Call( item.GetObject(), parms ); } } continue; @@ -1075,7 +1075,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject } InlineWordCode( constructsuper ) { - uint32 args = bitstream.ReadEncodedU32( ); + uint32 args = bitstream.ReadEncodedU32(); stack.Pop( args ); continue; } @@ -1083,9 +1083,9 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject { //no need to call constructors for props that const auto& cp = abcFile->constant_pool; - const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = abcFile->constant_pool.multinameInfos[bitstream.ReadEncodedU32()]; const idStrPtr propName = ( idStrPtr ) &cp.utf8Strings[mn.nameIndex]; - uint32 arg_count = bitstream.ReadEncodedU32( ); + uint32 arg_count = bitstream.ReadEncodedU32(); if( *propName == "Array" ) { for( int i = 0; i < arg_count; i++ ) @@ -1231,10 +1231,10 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject InlineWordCode( initproperty ) { const auto& cp = abcFile->constant_pool; - const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32( )]; + const auto& mn = cp.multinameInfos[bitstream.ReadEncodedU32()]; const auto& n = cp.utf8Strings[mn.nameIndex]; - idSWFScriptVar value = stack.A( ); + idSWFScriptVar value = stack.A(); stack.Pop( 1 ); stack.A().GetObject()->Set( n, value ); continue; @@ -1314,9 +1314,9 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject InlineWordCode( negate_i ) InlineWordCode( negate ) { - auto& val = stack.A( ); + auto& val = stack.A(); idSWFScriptVar result; - switch( val.GetType( ) ) + switch( val.GetType() ) { case idSWFScriptVar::SWF_VAR_FLOAT: val.SetFloat( -val.ToFloat() ); @@ -1325,16 +1325,16 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject val.SetInteger( -val.ToInteger() ); continue; default: - common->Warning( " Tried to increment incompatible type %s", val.TypeOf( ) ); + common->Warning( " Tried to increment incompatible type %s", val.TypeOf() ); } continue; } InlineWordCode( increment_i ) InlineWordCode( increment ) { - auto& val = stack.A( ); + auto& val = stack.A(); idSWFScriptVar result; - switch( val.GetType( ) ) + switch( val.GetType() ) { case idSWFScriptVar::SWF_VAR_FLOAT: val.SetFloat( val.ToFloat() + 1.0f ); @@ -1343,7 +1343,7 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject val.SetInteger( val.ToInteger() + 1 ); continue; default: - common->Warning( " Tried to increment incompatible type %s", val.TypeOf( ) ); + common->Warning( " Tried to increment incompatible type %s", val.TypeOf() ); } continue; } @@ -1414,22 +1414,22 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject auto& lH = stack.B(); auto& rH = stack.A(); idSWFScriptVar result; - switch( lH.GetType( ) ) + switch( lH.GetType() ) { case idSWFScriptVar::SWF_VAR_STRING: - result.SetString( lH.ToString( ) + rH.ToString( ) ); + result.SetString( lH.ToString() + rH.ToString() ); break; case idSWFScriptVar::SWF_VAR_FLOAT: - result.SetFloat( lH.ToFloat( ) + rH.ToFloat( ) ); + result.SetFloat( lH.ToFloat() + rH.ToFloat() ); break; case idSWFScriptVar::SWF_VAR_INTEGER: - result.SetInteger( lH.ToInteger( ) + rH.ToInteger( ) ); + result.SetInteger( lH.ToInteger() + rH.ToInteger() ); break; case idSWFScriptVar::SWF_VAR_FUNCTION: - result.SetString( lH.ToString( ) + rH.ToString( ) ); + result.SetString( lH.ToString() + rH.ToString() ); break; default: - common->Warning( " Tried to add incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + common->Warning( " Tried to add incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); } stack.Pop( 2 ); @@ -1442,16 +1442,16 @@ idSWFScriptVar idSWFScriptFunction_Script::RunAbc( idSWFScriptObject* thisObject auto& lH = stack.A(); auto& rH = stack.B(); idSWFScriptVar result; - switch( lH.GetType( ) ) + switch( lH.GetType() ) { case idSWFScriptVar::SWF_VAR_FLOAT: - result.SetFloat( lH.ToFloat( ) - rH.ToFloat( ) ); + result.SetFloat( lH.ToFloat() - rH.ToFloat() ); break; case idSWFScriptVar::SWF_VAR_INTEGER: - result.SetInteger( lH.ToInteger( ) - rH.ToInteger( ) ); + result.SetInteger( lH.ToInteger() - rH.ToInteger() ); break; default: - common->Warning( " Tried to subtract incompatible types %s + %s", lH.TypeOf( ), rH.TypeOf( ) ); + common->Warning( " Tried to subtract incompatible types %s + %s", lH.TypeOf(), rH.TypeOf() ); } stack.Pop( 2 ); diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 91a0afb81c..154da31462 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -91,7 +91,7 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) init->SetData( classInfo.cinit ); tmp->Set( "__initializer__", idSWFScriptVar( init ) ); init->SetAbcFile( &abcFile ); - idSWFScriptFunction_Script* constr = idSWFScriptFunction_Script::Alloc( ); + idSWFScriptFunction_Script* constr = idSWFScriptFunction_Script::Alloc(); constr->SetData( instanceInfo.iinit ); tmp->Set( "__constructor__", idSWFScriptVar( constr ) ); constr->SetAbcFile( &abcFile ); @@ -116,7 +116,7 @@ void idSWF::CreateAbcObjects( idSWFScriptObject* globals ) fullClassName += abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; idStr& className = abcFile.constant_pool.utf8Strings[instanceInfo.name->nameIndex]; idSWFScriptObject* tmp = globals->GetObject( fullClassName ); - auto* target = idSWFScriptObject::Alloc( ); + auto* target = idSWFScriptObject::Alloc(); auto* var = tmp->GetVariable( "[" + fullClassName + "]", true ); for( swfTraits_info& trait : instanceInfo.traits ) @@ -453,14 +453,14 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "_global", globals ); SWF_NATIVE_API_OBJECT_DECLARE( _global ); - auto* accessibilityPropertiesObj = idSWFScriptObject::Alloc( ); - //accessibilityPropertiesObj->Set( "", idSWFScriptObject::Alloc( ) ); + auto* accessibilityPropertiesObj = idSWFScriptObject::Alloc(); + //accessibilityPropertiesObj->Set( "", idSWFScriptObject::Alloc() ); - auto* dispatcherObj = idSWFScriptObject::Alloc( ); + auto* dispatcherObj = idSWFScriptObject::Alloc(); dispatcherObj->SetPrototype( &eventDispatcherScriptObjectPrototype ); extern idSWFScriptObject_SpriteInstancePrototype spriteInstanceScriptObjectPrototype; - auto* movieclipObj = idSWFScriptObject::Alloc( ); + auto* movieclipObj = idSWFScriptObject::Alloc(); movieclipObj->SetPrototype( &spriteInstanceScriptObjectPrototype ); if( spriteInstanceScriptObjectPrototype.GetPrototype() == NULL ) @@ -476,13 +476,13 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, globals->Set( "Array", arrayObj ); globals->Set( "Object", &scriptFunction_Object ); globals->Set( "EventDispatcher", dispatcherObj ); - globals->Set( "DisplayObject", idSWFScriptObject::Alloc( ) ); - globals->Set( "InteractiveObject", idSWFScriptObject::Alloc( ) ); + globals->Set( "DisplayObject", idSWFScriptObject::Alloc() ); + globals->Set( "InteractiveObject", idSWFScriptObject::Alloc() ); globals->Set( "AccessibilityProperties", accessibilityPropertiesObj ); globals->Set( "Dictionary", idSWFScriptObject::Alloc() ); - globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); - globals->Set( "Sprite", idSWFScriptObject::Alloc( ) ); - globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc( ) ); + globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc() ); + globals->Set( "Sprite", idSWFScriptObject::Alloc() ); + globals->Set( "DisplayObjectContainer", idSWFScriptObject::Alloc() ); globals->Set( "MovieClip", movieclipObj ); CreateAbcObjects( globals ); @@ -490,7 +490,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, mainspriteInstance = spriteInstanceAllocator.Alloc(); mainspriteInstance->abcFile = &abcFile; - mainspriteInstance->scriptObject = idSWFScriptObject::Alloc( ); + mainspriteInstance->scriptObject = idSWFScriptObject::Alloc(); //stage class. for( auto& symbol : symbolClasses.symbols ) @@ -501,11 +501,11 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_, bool exportJSON, idStr objName; mainspriteInstance->name.ExtractFileExtension( objName ); - auto* super = globals->Get( symbol.name ).GetObject( ); + auto* super = globals->Get( symbol.name ).GetObject(); auto dcopy = super->Get( "[" + symbol.name + "]" ); if( dcopy.IsObject() ) { - mainspriteInstance->scriptObject->DeepCopy( dcopy.GetObject( ) ); + mainspriteInstance->scriptObject->DeepCopy( dcopy.GetObject() ); } mainspriteInstance->scriptObject->SetPrototype( super ); diff --git a/neo/swf/SWF_ScriptFunction.cpp b/neo/swf/SWF_ScriptFunction.cpp index 36a158f631..6cc6e6eaad 100644 --- a/neo/swf/SWF_ScriptFunction.cpp +++ b/neo/swf/SWF_ScriptFunction.cpp @@ -306,7 +306,7 @@ idSWFScriptVar idSWFScriptFunction_Script::Call( idSWFScriptObject* thisObject, assert( methodInfo->body ); auto* body = methodInfo->body; registers[0].SetObject( thisObject ); - idSWFBitStream abcStream( body->code.Ptr( ), body->codeLength, false ); + idSWFBitStream abcStream( body->code.Ptr(), body->codeLength, false ); retVal = RunAbc( thisObject, stack, abcStream ); //-- FIXME diff --git a/neo/swf/SWF_ScriptFunction.h b/neo/swf/SWF_ScriptFunction.h index d3b6c87a30..eaef35cdd1 100644 --- a/neo/swf/SWF_ScriptFunction.h +++ b/neo/swf/SWF_ScriptFunction.h @@ -247,7 +247,7 @@ class idSWFScriptFunction_Script : public idSWFScriptFunction { abcFile = _file; } - swfMethod_info* GetMethodInfo( ) + swfMethod_info* GetMethodInfo() { return methodInfo; } diff --git a/neo/swf/SWF_ScriptObject.cpp b/neo/swf/SWF_ScriptObject.cpp index b310766b79..ecacac5399 100644 --- a/neo/swf/SWF_ScriptObject.cpp +++ b/neo/swf/SWF_ScriptObject.cpp @@ -63,7 +63,7 @@ void idSWFScriptObject::DeepCopy( idSWFScriptObject* _object ) { if( _object != NULL ) { - for( int i = 0; i < _object->NumVariables( ); i++ ) + for( int i = 0; i < _object->NumVariables(); i++ ) { Set( _object->EnumVariable( i ), _object->Get( _object->EnumVariable( i ) ) ); } diff --git a/neo/swf/SWF_SpriteInstance.cpp b/neo/swf/SWF_SpriteInstance.cpp index 9c4a967c76..cc2f11e8dc 100644 --- a/neo/swf/SWF_SpriteInstance.cpp +++ b/neo/swf/SWF_SpriteInstance.cpp @@ -221,8 +221,8 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte display.spriteInstance->abcFile = this->abcFile; if( dictEntry->scriptClass.IsValid() ) { - display.spriteInstance->scriptObject = idSWFScriptObject::Alloc( ); - auto* super = dictEntry->scriptClass.GetObject( ); + display.spriteInstance->scriptObject = idSWFScriptObject::Alloc(); + auto* super = dictEntry->scriptClass.GetObject(); auto dcopy = super->Get( *dictEntry->name ); if( dcopy.IsObject() ) @@ -240,9 +240,9 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte { display.textInstance = sprite->swf->textInstanceAllocator.Alloc(); - if( dictEntry->scriptClass.IsValid( ) ) + if( dictEntry->scriptClass.IsValid() ) { - auto* super = dictEntry->scriptClass.GetObject( ); + auto* super = dictEntry->scriptClass.GetObject(); auto dcopy = super->Get( *dictEntry->name ); if( dcopy.IsObject() ) { @@ -256,8 +256,8 @@ swfDisplayEntry_t* idSWFSpriteInstance::AddDisplayEntry( int depth, int characte } else if( dictEntry->type == SWF_DICT_TEXT ) { - //display.textInstance = sprite->swf->textInstanceAllocator.Alloc( ); - //display.textInstance->Init( dictEntry->text, sprite->GetSWF( ) ); + //display.textInstance = sprite->swf->textInstanceAllocator.Alloc(); + //display.textInstance->Init( dictEntry->text, sprite->GetSWF() ); } } return &display; diff --git a/neo/swf/SWF_TextInstance.cpp b/neo/swf/SWF_TextInstance.cpp index f8379458a3..a15794c0ac 100644 --- a/neo/swf/SWF_TextInstance.cpp +++ b/neo/swf/SWF_TextInstance.cpp @@ -131,12 +131,12 @@ void idSWFTextInstance::Init( idSWFText* _text, idSWF* _swf ) inputTextStartChar = 0; - renderDelay = swf_textRndLetterDelay.GetInteger( ); + renderDelay = swf_textRndLetterDelay.GetInteger(); needsSoundUpdate = false; useDropShadow = false; useStroke = false; strokeStrength = 1.0f; - strokeWeight = swf_textStrokeSize.GetFloat( ); + strokeWeight = swf_textStrokeSize.GetFloat(); scriptObject.SetPrototype( &textInstanceScriptObjectPrototype ); scriptObject.SetText( this );