Amineri Posted March 17, 2013 Share Posted March 17, 2013 I came across this document on the epic games (maker of Unreal Engine) regarding how Actionscript is integrated with the Unreal Engine 3. http://udn.epicgames.com/Three/ScaleformTechnicalGuide.html It's based on the GFxMovieplayer class... I'm still reading through it, but figured I'd post it up for those people more Flash-media savvy than me. P.S. This is the key (I think) to being able to modify most of the UI stuff that has been, up to now, inaccessible. Link to comment Share on other sites More sharing options...
Amineri Posted March 17, 2013 Author Share Posted March 17, 2013 So, I read through some of the Unreal Engine documentation, and it looks like Unreal Engine 3 supports embedding SWF files into Unreal Engine 3. Basically, you hang a /Flash directory off your main game directory and put the SWF files you want to import in there. Subdirectories work, too. On import, the "/" in the path name are converted into ".". Their example: For instance C:\UDK\UDK-2010-07\UDKGame\Flash\example\SomeFile.swf would be imported as SwfMovie'example.SomeFile'. They further explain how you call the imported SWF function: So, for example, if you wanted to call the following ActionScript function: public function MyActionScriptFunc(param1:String,param2:Object):Void{ // Do something awesome!}From UnrealScript, you would create the following function: function CallMyActionScriptFunc(string Param1, GFxObject Param2){ ActionScriptVoid("MyActionScriptFunc");}When called, the integration code will check the parameter list of CallMyActionScriptFunc, and convert those parameters to their Scaleform equivalents, and call the function in ActionScript. For ActionScript functions with return types, the other ActionScript* methods in GFxObject can be used. The return values for these functions will be the return values from ActionScript. This explains the UE Explorer decompiled references such as: protected simulated function AS_AddInventoryItem(int Type, string Title, string imgLabel, int numEquipableItems){manager.ActionScriptVoid(string(GetMCPath()) $ ".AddInventoryItem");} In this case, AddInventoryItem is the name of the SWF script that was imported into UE3. The single "." at the beginning would mean that it was in the root, but the concatenation of GetMCPath() to the beginning may be adding on to that. Regardless, the ActionScript seems like it should be sitting somewhere in the upk files. I did a manual search through the XcomStrategyGame.upk (unpacked) with a hex editor to search for the string "AddInventoryItem" -- since the ActionScript is being referenced via string (original SWF filename), I searched for the string, but didn't find anything useful. Link to comment Share on other sites More sharing options...
anUser Posted March 17, 2013 Share Posted March 17, 2013 I'm not sure I get what it means exactly or the implications it has. Is it only for UI editing and cinematics or could we actually write functions (in plain text) in actionscript and then call them from within the upk (given that we hex program a wrapper function in the upk)? If so, could it reach further than UI and cinematics? Link to comment Share on other sites More sharing options...
Amineri Posted March 17, 2013 Author Share Posted March 17, 2013 One example of a mod that it should allow is to increase the number of soldiers beyond 6. Another would be to increase the number of interceptors per continent beyond 4. From what I read, both of these mod changes were defeated by the inability to get at the actionscript that actually runs the UI. Beyond that I have no idea what could be put into the actionscript parts. I'd imagine it's whatever sort of compiled byte-code that Flash files use, however? I know nothing about web coding, so can't say anything with any confidence in this area. Link to comment Share on other sites More sharing options...
johnnylump Posted March 17, 2013 Share Posted March 17, 2013 (edited) I suggest you read the following thread if you haven't alreadyhttp://forums.nexusmods.com/index.php?/topic/888272-ui-editing/?hl=%2Bactionscript&do=findComment&comment=7188965 The upshot is that it's possible. I was trying to get 5 interceptors, and indeed got it in every place but one: I hit a wall with a small but critical function and lack of knowledge of Actionscript bytecodes. I'm better at hex editing now, and it may be worth another try, but a key thing to figure out is what a null byte is in ActionScript. Another difficulty is finding an ActionScript decompiler that's both thorough and free. I had to use two different ones to triangulate the things to change, and one of those has since expired. Edited March 17, 2013 by johnnylump Link to comment Share on other sites More sharing options...
Amineri Posted March 17, 2013 Author Share Posted March 17, 2013 Wow, that forum link was from -months- ago :o ... I didn't know that you'd made that much progress with the Actionscript. I had just seen all the posts about how people were beating their heads against the wall with it. Hopefully someone familiar with Flash programming sees this and will help out. Link to comment Share on other sites More sharing options...
anUser Posted March 17, 2013 Share Posted March 17, 2013 (edited) I see... so basically we're hex editing inside the upk's, but with the handicap that we must use ActionScript to change those parts, isn't it? Well in any case it's good to know edit: unfortunately I'm not familiar at all with AS. I do web programming but now they only teach us html5. Flash is kaput! :) Edited March 17, 2013 by anUser Link to comment Share on other sites More sharing options...
johnnylump Posted March 17, 2013 Share Posted March 17, 2013 (edited) Right, it's more hex editing, mostly in command1.upk, from what I can tell. (And a much more complex process of extracting the code, as noted in the link). But it's different hex and different bytecodes than we've been using for our upk edits so far. Basically I got as far as simple upk editing -- making constant and sign changes. True rescripting, like we're managing with UnrealScript, will take some additional discoveries. Perhaps someone has posted on the Internet somewhere what ActionScript bytecodes are. Otherwise, what may be necessary is building a table of bytecodes based on what a decompiler tells us. Eliot has said he may try to put together an swf extraction tool the future, although a full decompiler is probably asking too much. And, by the way, if anyone can figure out how to add additional troopers to the tactical game, you'll have achieved the holy grail of X-Com modding. Edited March 17, 2013 by johnnylump Link to comment Share on other sites More sharing options...
Amineri Posted March 17, 2013 Author Share Posted March 17, 2013 I found the file below -- it lists the operators, if not the actual hex values, but the operators are listed as part of enumerated list, so presumably the order corresponds to hex increments -- just not sure what the start point for each is. /** format - haXe File Formats* ABC and SWF support by Nicolas Cannasse** Copyright © 2008, The haXe Project Contributors* All rights reserved.* Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:** - Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* - Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.** THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH* DAMAGE.*/package format.abc;enum Index<T> { Idx( v : Int );}enum Namespace { NPrivate( ns : Index<String> ); NNamespace( ns : Index<String> ); NPublic( ns : Index<String> ); NInternal( ns : Index<String> ); NProtected( ns : Index<String> ); NExplicit( ns : Index<String> ); NStaticProtected( ns : Index<String> );}typedef NamespaceSet = Array<Index<Namespace>>enum Name { NName( name : Index<String>, ns : Index<Namespace> ); NMulti( name : Index<String>, ns : Index<NamespaceSet> ); NRuntime( name : Index<String> ); NRuntimeLate; NMultiLate( nset : Index<NamespaceSet> ); NAttrib( n : Name ); NParams( n : IName, params : Array<IName> );}typedef MethodType = { var args : Array<Null<IName>>; var ret : Null<IName>; var extra : Null<MethodTypeExtra>;}typedef MethodTypeExtra = { var native : Bool; var variableArgs : Bool; var argumentsDefined : Bool; var usesDXNS : Bool; var newBlock : Bool; var unused : Bool; var debugName : Null<Index<String>>; var defaultParameters : Null<Array<Value>>; var paramNames : Null<Array<Null<Index<String>>>>;}enum Value { VNull; VBool( b : Bool ); VString( i : Index<String> ); VInt( i : Index<#if haxe3 Int #else haxe.Int32 #end> ); VUInt( i : Index<#if haxe3 Int #else haxe.Int32 #end> ); VFloat( f : Index<Float> ); VNamespace( kind : Int, ns : Index<Namespace> );}typedef TryCatch = { var start : Int; var end : Int; var handle : Int; var type : Null<IName>; var variable : Null<IName>;}typedef Function = { var type : Index<MethodType>; var maxStack : Int; var nRegs : Int; var initScope : Int; var maxScope : Int; var code : haxe.io.Bytes; var trys : Array<TryCatch>; var locals : Array<Field>;}typedef Field = { var name : IName; var slot : Slot; var kind : FieldKind; var metadatas : Null<Array<Index<Metadata>>>;}enum MethodKind { KNormal; KGetter; KSetter;}enum FieldKind { FVar( ?type : Null<IName>, ?value : Value, ?const : Bool ); FMethod( type : Index<MethodType>, k : MethodKind, ?isFinal : Bool, ?isOverride : Bool ); FClass( c : Index<ClassDef> ); FFunction( f : Index<MethodType> );}typedef ClassDef = { var name : IName; var superclass : Null<IName>; var interfaces : Array<IName>; var constructor : Index<MethodType>; var fields : Array<Field>; var namespace : Null<Index<Namespace>>; var isSealed : Bool; var isFinal : Bool; var isInterface : Bool; var statics : Index<MethodType>; var staticFields : Array<Field>;}typedef Metadata = { var name : Index<String>; var data : Array<{ n : Null<Index<String>>, v : Index<String> }>;}typedef Init = { var method : Index<MethodType>; var fields : Array<Field>;}class ABCData { public var ints : Array<#if haxe3 Int #else haxe.Int32 #end>; public var uints : Array<#if haxe3 Int #else haxe.Int32 #end>; public var floats : Array<Float>; public var strings : Array<String>; public var namespaces : Array<Namespace>; public var nssets : Array<NamespaceSet>; public var names : Array<Name>; public var methodTypes : Array<MethodType>; public var metadatas : Array<Metadata>; public var classes : Array<ClassDef>; public var inits : Array<Init>; public var functions : Array<Function>; public function get<T>( t : Array<T>, i : Index<T> ) : T { return switch( i ) { case Idx(n): t[n-1]; }; } public function new() { }}typedef IName = Index<Name>typedef Slot = Inttypedef Register = Intenum OpCode { OBreakPoint; ONop; OThrow; OGetSuper( v : IName ); OSetSuper( v : IName ); ODxNs( v : Index<String> ); ODxNsLate; ORegKill( r : Register ); OLabel; OJump( j : JumpStyle, delta : Int ); OSwitch( def : Int, deltas : Array<Int> ); OPushWith; OPopScope; OForIn; OHasNext; ONull; OUndefined; OForEach; OSmallInt( v : Int ); OInt( v : Int ); OTrue; OFalse; ONaN; OPop; ODup; OSwap; OString( v : Index<String> ); OIntRef( v : Index<#if haxe3 Int #else haxe.Int32 #end> ); OUIntRef( v : Index<#if haxe3 Int #else haxe.Int32 #end> ); OFloat( v : Index<Float> ); OScope; ONamespace( v : Index<Namespace> ); ONext( r1 : Register, r2 : Register ); OFunction( f : Index<MethodType> ); OCallStack( nargs : Int ); OConstruct( nargs : Int ); OCallMethod( slot : Slot, nargs : Int ); OCallStatic( meth : Index<MethodType>, nargs : Int ); OCallSuper( name : IName, nargs : Int ); OCallProperty( name : IName, nargs : Int ); ORetVoid; ORet; OConstructSuper( nargs : Int ); OConstructProperty( name : IName, nargs : Int ); OCallPropLex( name : IName, nargs : Int ); OCallSuperVoid( name : IName, nargs : Int ); OCallPropVoid( name : IName, nargs : Int ); OApplyType( nargs : Int ); OObject( nfields : Int ); OArray( nvalues : Int ); ONewBlock; OClassDef( c : Index<ClassDef> ); OGetDescendants( c : IName ); OCatch( c : Int ); OFindPropStrict( p : IName ); OFindProp( p : IName ); OFindDefinition( d : IName ); OGetLex( p : IName ); OSetProp( p : IName ); OReg( r : Register ); OSetReg( r : Register ); OGetGlobalScope; OGetScope( n : Int ); OGetProp( p : IName ); OInitProp( p : IName ); ODeleteProp( p : IName ); OGetSlot( s : Slot ); OSetSlot( s : Slot ); OToString; OToXml; OToXmlAttr; OToInt; OToUInt; OToNumber; OToBool; OToObject; OCheckIsXml; OCast( t : IName ); OAsAny; OAsString; OAsType( t : IName ); OAsObject; OIncrReg( r : Register ); ODecrReg( r : Register ); OTypeof; OInstanceOf; OIsType( t : IName ); OIncrIReg( r : Register ); ODecrIReg( r : Register ); OThis; OSetThis; ODebugReg( name : Index<String>, r : Register, line : Int ); ODebugLine( line : Int ); ODebugFile( file : Index<String> ); OBreakPointLine( n : Int ); OTimestamp; OOp( op : Operation ); OUnknown( byte : Int );}enum JumpStyle { JNotLt; JNotLte; JNotGt; JNotGte; JAlways; JTrue; JFalse; JEq; JNeq; JLt; JLte; JGt; JGte; JPhysEq; JPhysNeq;}enum Operation { OpAs; OpNeg; OpIncr; OpDecr; OpNot; OpBitNot; OpAdd; OpSub; OpMul; OpDiv; OpMod; OpShl; OpShr; OpUShr; OpAnd; OpOr; OpXor; OpEq; OpPhysEq; OpLt; OpLte; OpGt; OpGte; OpIs; OpIn; OpIIncr; OpIDecr; OpINeg; OpIAdd; OpISub; OpIMul; OpMemGet8; OpMemGet16; OpMemGet32; OpMemGetFloat; OpMemGetDouble; OpMemSet8; OpMemSet16; OpMemSet32; OpMemSetFloat; OpMemSetDouble; OpSign1; OpSign8; OpSign16;} Here is some code (from the same source) that purports to read the hex and convert to the opcodes: /** format - haXe File Formats* ABC and SWF support by Nicolas Cannasse** Copyright © 2008, The haXe Project Contributors* All rights reserved.* Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:** - Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* - Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.** THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE* DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH* DAMAGE.*/package format.abc;import format.abc.Data;#if !haxe3import haxe.Int32;#endclass OpReader { public var i : haxe.io.Input; public function new(i) { this.i = i; } public function readInt() { var a = i.readByte(); if( a < 128 ) return a; a &= 0x7F; var b = i.readByte(); if( b < 128 ) return (b << 7) | a; b &= 0x7F; var c = i.readByte(); if( c < 128 ) return (c << 14) | (b << 7) | a; c &= 0x7F; var d = i.readByte(); if( d < 128 ) return (d << 21) | (c << 14) | (b << 7) | a; d &= 0x7F; var e = i.readByte(); if( e > 15 ) throw "assert"; if( ((e & :cool: == 0) != ((e & 4) == 0) ) throw haxe.io.Error.Overflow; return (e << 28) | (d << 21) | (c << 14) | (b << 7) | a; } inline function readIndex<T>() : Index<T> { return Idx(readInt()); } #if haxe3 public function readInt32() : Int { var a = i.readByte(); if( a < 128 ) return a; a &= 0x7F; var b = i.readByte(); if( b < 128 ) return (b << 7) | a; b &= 0x7F; var c = i.readByte(); if( c < 128 ) return (c << 14) | (b << 7) | a; c &= 0x7F; var d = i.readByte(); if( d < 128 ) return (d << 21) | (c << 14) | (b << 7) | a; d &= 0x7F; var e = i.readByte(); if( e > 15 ) throw "assert"; return (e << 28) | (d << 21) | (c << 14) | (b << 7) | a; } #else public function readInt32() : Int32 { var a = i.readByte(); if( a < 128 ) return Int32.ofInt(a); a &= 0x7F; var b = i.readByte(); if( b < 128 ) return Int32.ofInt((b << 7) | a); b &= 0x7F; var c = i.readByte(); if( c < 128 ) return Int32.ofInt((c << 14) | (b << 7) | a); c &= 0x7F; var d = i.readByte(); if( d < 128 ) return Int32.ofInt((d << 21) | (c << 14) | (b << 7) | a); d &= 0x7F; var e = i.readByte(); if( e > 15 ) throw "assert"; var small = Int32.ofInt((d << 21) | (c << 14) | (b << 7) | a); var big = Int32.shl(Int32.ofInt(e),28); return Int32.or(big,small); } #end inline function reg() { return i.readByte(); } inline function jmp(j) { return OJump(j,i.readInt24()); } public function readOp(op) { return switch( op ) { case 0x01: OBreakPoint; case 0x02: ONop; case 0x03: OThrow; case 0x04: OGetSuper(readIndex()); case 0x05: OSetSuper(readIndex()); case 0x06: ODxNs(readIndex()); case 0x07: ODxNsLate; case 0x08: ORegKill(reg()); case 0x09: OLabel; case 0x0C: jmp(JNotLt); case 0x0D: jmp(JNotLte); case 0x0E: jmp(JNotGt); case 0x0F: jmp(JNotGte); case 0x10: jmp(JAlways); case 0x11: jmp(JTrue); case 0x12: jmp(JFalse); case 0x13: jmp(JEq); case 0x14: jmp(JNeq); case 0x15: jmp(JLt); case 0x16: jmp(JLte); case 0x17: jmp(JGt); case 0x18: jmp(JGte); case 0x19: jmp(JPhysEq); case 0x1A: jmp(JPhysNeq); case 0x1B: var def = i.readInt24(); var cases = new Array(); for( _ in 0...readInt() + 1 ) cases.push(i.readInt24()); OSwitch(def,cases); case 0x1C: OPushWith; case 0x1D: OPopScope; case 0x1E: OForIn; case 0x1F: OHasNext; case 0x20: ONull; case 0x21: OUndefined; case 0x23: OForEach; case 0x24: OSmallInt(i.readInt8()); case 0x25: OInt(readInt()); case 0x26: OTrue; case 0x27: OFalse; case 0x28: ONaN; case 0x29: OPop; case 0x2A: ODup; case 0x2B: OSwap; case 0x2C: OString(readIndex()); case 0x2D: OIntRef(readIndex()); case 0x2E: OUIntRef(readIndex()); case 0x2F: OFloat(readIndex()); case 0x30: OScope; case 0x31: ONamespace(readIndex()); case 0x32: var r1 = readInt(); var r2 = readInt(); ONext(r1,r2); case 0x35: OOp(OpMemGet8); case 0x36: OOp(OpMemGet16); case 0x37: OOp(OpMemGet32); case 0x38: OOp(OpMemGetFloat); case 0x39: OOp(OpMemGetDouble); case 0x3A: OOp(OpMemSet8); case 0x3B: OOp(OpMemSet16); case 0x3C: OOp(OpMemSet32); case 0x3D: OOp(OpMemSetFloat); case 0x3E: OOp(OpMemSetDouble); case 0x40: OFunction(readIndex()); case 0x41: OCallStack(readInt()); case 0x42: OConstruct(readInt()); case 0x43: var s = readInt(); var n = readInt(); OCallMethod(s,n); case 0x44: var m = readIndex(); var n = readInt(); OCallStatic(m,n); case 0x45: var p = readIndex(); var n = readInt(); OCallSuper(p,n); case 0x46: var p = readIndex(); var n = readInt(); OCallProperty(p,n); case 0x47: ORetVoid; case 0x48: ORet; case 0x49: OConstructSuper(readInt()); case 0x4A: var p = readIndex(); var n = readInt(); OConstructProperty(p,n); case 0x4C: var p = readIndex(); var n = readInt(); OCallPropLex(p,n); case 0x4E: var p = readIndex(); var n = readInt(); OCallSuperVoid(p,n); case 0x4F: var p = readIndex(); var n = readInt(); OCallPropVoid(p,n); case 0x50: OOp(OpSign1); case 0x51: OOp(OpSign8); case 0x52: OOp(OpSign16); case 0x53: OApplyType(readInt()); case 0x55: OObject(readInt()); case 0x56: OArray(readInt()); case 0x57: ONewBlock; case 0x58: OClassDef(readIndex()); case 0x59: OGetDescendants(readIndex()); case 0x5A: OCatch(readInt()); case 0x5D: OFindPropStrict(readIndex()); case 0x5E: OFindProp(readIndex()); case 0x5F: OFindDefinition(readIndex()); case 0x60: OGetLex(readIndex()); case 0x61: OSetProp(readIndex()); case 0x62: OReg(reg()); case 0x63: OSetReg(reg()); case 0x64: OGetGlobalScope; case 0x65: OGetScope(i.readByte()); case 0x66: OGetProp(readIndex()); case 0x68: OInitProp(readIndex()); case 0x6A: ODeleteProp(readIndex()); case 0x6C: OGetSlot(readInt()); case 0x6D: OSetSlot(readInt()); case 0x70: OToString; case 0x71: OToXml; case 0x72: OToXmlAttr; case 0x73: OToInt; case 0x74: OToUInt; case 0x75: OToNumber; case 0x76: OToBool; case 0x77: OToObject; case 0x78: OCheckIsXml; case 0x80: OCast(readIndex()); case 0x82: OAsAny; case 0x85: OAsString; case 0x86: OAsType(readIndex()); case 0x87: OOp(OpAs); case 0x89: OAsObject; case 0x90: OOp(OpNeg); case 0x91: OOp(OpIncr); case 0x92: OIncrReg(reg()); case 0x93: OOp(OpDecr); case 0x94: ODecrReg(reg()); case 0x95: OTypeof; case 0x96: OOp(OpNot); case 0x97: OOp(OpBitNot); case 0xA0: OOp(OpAdd); case 0xA1: OOp(OpSub); case 0xA2: OOp(OpMul); case 0xA3: OOp(OpDiv); case 0xA4: OOp(OpMod); case 0xA5: OOp(OpShl); case 0xA6: OOp(OpShr); case 0xA7: OOp(OpUShr); case 0xA8: OOp(OpAnd); case 0xA9: OOp(OpOr); case 0xAA: OOp(OpXor); case 0xAB: OOp(OpEq); case 0xAC: OOp(OpPhysEq); case 0xAD: OOp(OpLt); case 0xAE: OOp(OpLte); case 0xAF: OOp(OpGt); case 0xB0: OOp(OpGte); case 0xB1: OInstanceOf; case 0xB2: OIsType(readIndex()); case 0xB3: OOp(OpIs); case 0xB4: OOp(OpIn); case 0xC0: OOp(OpIIncr); case 0xC1: OOp(OpIDecr); case 0xC2: OIncrIReg(reg()); case 0xC3: ODecrIReg(reg()); case 0xC4: OOp(OpINeg); case 0xC5: OOp(OpIAdd); case 0xC6: OOp(OpISub); case 0xC7: OOp(OpIMul); case 0xD0: OThis; case 0xD1: OReg(1); case 0xD2: OReg(2); case 0xD3: OReg(3); case 0xD4: OSetThis; case 0xD5: OSetReg(1); case 0xD6: OSetReg(2); case 0xD7: OSetReg(3); case 0xEF: if( i.readByte() != 1 ) throw "assert"; var name = readIndex(); var r = reg(); var line = readInt(); ODebugReg(name,r,line); case 0xF0: ODebugLine(readInt()); case 0xF1: ODebugFile(readIndex()); case 0xF2: OBreakPointLine(readInt()); case 0xF3: OTimestamp; default: OUnknown(op); } } public static function decode( i : haxe.io.Input ) { var opr = new OpReader(i); var ops = new Array(); while( true ) { var op; try op = i.readByte() catch( e : haxe.io.Eof ) break; ops.push(opr.readOp(op)); } return ops; }} Link to comment Share on other sites More sharing options...
Recommended Posts