Jump to content

Photo

UI Editing


  • Please log in to reply
54 replies to this topic

#1
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts
So I was working on adding an fifth interceptor slot on each continent. Through upk edits (changing 4 to 5 in a half-dozen places), I have it so you can buy 5 per continent and see them on the hangar screen, change weapons, etc. They refuel and repair work fine, except for one important thing:

The problem comes when I hit the "UFO contact" screen, where you have the interface that allows you to select and launch which interceptor you want to fight the incoming UFO. The interface only shows the first four interceptors on the right-hand side. There's definitely space for a fifth interceptor, so it's not a screen size issue. You can use the arrow keys to pick and launch the invisible fifth interceptor with the return key, but that's a suboptimal outcome.

This data for the interface is filled out in XComStrategyGame.upk, class XGInterceptionUI, particularly function "UpdateSquadron."

The interface itself is called from UIMissionControl_UFORadarContactAlert. It creates a "state" called ShipSelection, which calls function UpdateData.

UpdateData calls another function, AS_AddShip, and I believe it's called five times when all five interceptor slots are filled. Now, AS_Addship calls only this line:

manager.ActionScriptVoid(string(GetMCPath()) $ ".AddShip");

"ActionScriptVoid" is a content-free function in GFxUI.upk, class GFxObject.

I gather this is calling an external Flash "ActionScript" script called "AddShip," and this controls the little boxes that let you select your interceptor, and I'm guessing it limits the number to four boxes, because I can't see anything else that would do this. But I don't know where to find this script, or whether it can be edited at this point.

I imagine this is a simpler version of the same problem some of you have encountered trying to add additional slots to the equip-your-squad screen, in service of increased squad sizes.

Are ActionScripts find-able and edit-able at this point, even with a hex editor? Or is this a dead-end?

#2
twinj

twinj

    Enthusiast

  • Members
  • PipPip
  • 113 posts
I tried to find this for Squad sizes but could not so I attempted to rewrite the current Squad select boxes to enable scrolling so as to select soldiers. Hit another UI brick wall which would not allow me to redraw the soldiers when the boxes scrolled. Otherwise I almost made it..

Drakous hit the same problem with UFO abductions...

If you find the solution you will become King. It is the next big step in modding XCOM we need.

Wish I could help.

Daemonjax was going to write a java patcher for this.. but he's disappeared so probably has no time for this game anymore.

I'll have another look at it when I have finished making a full UPK parser which could be used to create said patches.

#3
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts
Thanks for the reply; I guess we're hitting the same wall.

Have you found where the function GetMCPath() is, and where it points to?

And do we think the ActionScripts are embedded in the upk files? I can't find any swf or swc files anywhere in the game.

#4
twinj

twinj

    Enthusiast

  • Members
  • PipPip
  • 113 posts

Thanks for the reply; I guess we're hitting the same wall.

Have you found where the function GetMCPath() is, and where it points to?

And do we think the ActionScripts are embedded in the upk files? I can't find any swf or swc files anywhere in the game.


It is a native function in the XComGame.UI_FxScreen class.

// Export UUI_FxsScreen::execGetMCPath(FFrame&, void* const)
native simulated function name GetMCPath();

I have looked through the tfc's but only a little since I dont understand textures and maps.. yet.

Tis why I was hoping someone else would have a go (a previous request post of mine).

I am have another quick look now. But really need to understand how native functions work. Looks like delegates..

#5
bokauk

bokauk

    Fan

  • Members
  • PipPipPip
  • 483 posts

I am have another quick look now. But really need to understand how native functions work. Looks like delegates..

Not sure if this helps, but Capyvara had some success with a native function to enable the console.

I attempted his method, but the function name didn't seem to be listed. There are many other native functions that would be useful to manipulate, so it would be good if someone else could better understand this and get it to work :)

#6
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts
After researching a bunch of stuff you guys probably already know, all I can guess is that the ActionScripts are in the upks, but without a reader/decompiler that can take those on, we're hosed.

Has anyone tried an swf decompiler on a upk file?

Edited by johnnylump, 18 January 2013 - 02:32 AM.


#7
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts

After researching a bunch of stuff you guys probably already know, all I can guess is that the ActionScripts are in the upks, but without a reader/decompiler that can take those on, we're hosed.

Has anyone tried an swf decompiler on a upk file?


All right, I'm reading actionscript in a upk file. I'm a bit over my head here and may be duplicating stuff that may have already been solved, but I'll lay out what I did anyway:

(This method I found way back in an October post by dumbo111, so full credit there)

- Pick the upk you want to open and make a copy of the file, because this will ruin the upk.
- open the new file in a hex editor.
- look for the ansi string 'GFX' (in caps, just like that), delete everything before those letters.
- change GFX to FWS.
- save the file and rename it to .swf
- run a SWF decompiler on the swf file. (I'm using this one: - http://code.google.com/p/asdec/, but it gets plenty of "unsupported by decompiler" errors in the code)

I can triangulate back to the hex of the upk by searching for strings that appear in the ActionScript, but I haven't tried changing anything yet.

Hope this helps.

Update:
All the ActionScript function names I'm searching for show up in text searches of command1.upk and GlobalPersistentCookerData.upk, so I suspect they are in one of those.

I did the above trick on command1.upk (generating an swf file that can be decompiled), but the decompiled scripts are very ... generic in nature and don't contain specific stuff relating to Fighter or Squad selection UI.

(Thought before bedtime: there are multiple GFX lines in command1.upk; what if there are multiple swf files inside command1.upk, and each one needs to be broken out separately for decompiling? Maybe I'm only looking at the first of several swfs. Next thing to try. (Yep, that appears to be the case. Looks like there's as many as 45 swf files in command1.upk)

The trick doesn't look like it will work on GlobalPCD.upk, so there may be some better way to dig actionscripts out of the upk files.

Edited by johnnylump, 19 January 2013 - 05:27 AM.


#8
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts
I've edited some ActionScript within a upk file for the first time.

Here's what to do:
1) Get the name of the ActionScript you want to edit. In UE Explorer, it's the text string called from an "ActionScriptVoid" or other function starting with "ActionScript," like ActionScriptFloat. These appear to be called from unreal functions beginning with "AS_" in various classes.

2) Figure out which upk the ActionScript appears in. I finally started using grep to text search the entire uncompressed set of upks. You'll have to hunt around, as you might find function calls rather than the function itself. For interface editing, Command1.upk appears to have lots of ActionScript sections, although XComGame.upk has one or two, as well.

3) Now you have to excise the .swf containing the Actionscript file from within the .upk. UPKs can hold multiple SWF files.

4) SWF files begin with the three letters "GFX" (all uppercase) within the upk. In your hex editor, do an ANSI search for the ActionScript function name you want to edit. Then, search the ANSI *UP* from there for the letters GFX. Look at the context in which GFX appears -- if it looks like it's part of a function name, and not a standalone code, then search upward again.

5) Delete every single byte in the file BEFORE the letters GFX, all the way to the beginning.

6) Change the letters GFX to FWS. These should be the first three bytes of your new file. This allows decompilers to threat it as a distinct file (Thanks to Dumbo111 for this trick)

7) Save the file as an .SWF file -- do NOT save as a upk, as you've already ruined this file as a upk, and you want to keep your original intact. There may be additional ActionScripts in separate SWFs below the SWF you want to edit, but you won't be able to get at it without excising each one separately.

8 ) Open the file in an swf / ActionScript decompiler. I started using SoThink's decompiler, which has a 30-day trial limit, and there may be better editors out there. But I was able to translate the commands to hex (by looking at the "raw data" option and matching the assembler commands to the ActionScript) and make changes to in Notepad++ to the hex OF THE ORIGINAL UPK. (In other words, extract the swf section for observation purposes, but make your edits to the original upk.)

That's as far as I've gotten. Returning to the original issue, I found the "Addship" function within one of the swfs in command1.upk, Action section, sprite 672 (__Packages.RadarContactAlert). I changed the variable MAX_NUM_INTERCEPTORS from 4 to 5 within the following unique hex change in command1.upk:
96 09 00 04 01 08 0f 07 04
to
96 09 00 04 01 08 0f 07 05

Posted Image

Update: I confirmed changes to the ActionScript in Command1.upk are in fact implemented in the game, without having to use XShape.

This particular change didn't have a visible impact in the game that I can see, because I need to make additional changes elsewhere. I'm going to look some more, but it may be I would need to add several lines of scripting (rather than just change a single byte constant) to get the fifth interceptor to show up on the launch screen, and I'm not sure how to do that, or whether I have to stay within a byte limit like with the unreal scripts we're already editing. But if there are single variables and signs we can change to have a meaningful impact, then I think that's within our capability now.

Perhaps we can beg Eliot to include an ActionScript viewer within future versions of UExplorer (that can handle multiple SWF files).

Edited by johnnylump, 23 January 2013 - 04:14 AM.


#9
johnnylump

johnnylump

    Resident poster

  • Supporter
  • PipPipPipPipPip
  • 7,424 posts
I believe I have figured out why I can't add a 5th interceptor to the launch-interceptor UI. This may be a dead end, unless I figure out how to add another line of code to a small function without breaking the upk.

Essentially the upk function calls UI actionscript which calls a "shiplist" sprite that is, unfortunately, set to display only four ship sprites (not very robust coding, I must say; I'm not sure why a simple for loop was out of the question). This code is within of the swf files embedded in command1.upk:

Name: DefineSprite
Type: 39
Position: 46134
Length: 96
RecordHeader: long

<DefineSprite id='226'>
  <!-- sprite framecount=1 -->
  <PlaceObject2 idref='225' name='ship0' depth='1' matrix='t7041,-576'/>
  <PlaceObject2 idref='225' name='ship1' depth='14' matrix='t7041,2199'/>
  <PlaceObject2 idref='225' name='ship2' depth='27' matrix='t7041,4974'/>
  <PlaceObject2 idref='225' name='ship3' depth='40' matrix='t7041,7749'/>
  <ShowFrame/>
</DefineSprite>


Hex:
ff 09 60 00 00 00 e2 00 01 00 bf 06 10 00 00 00 		| **`************* |
26 01 00 e1 00 1c dc 0f b8 00 73 68 69 70 30 00 		| &*********ship0* |
bf 06 10 00 00 00 26 0e 00 e1 00 1c dc 09 12 e0 		| ******&********* |
73 68 69 70 31 00 bf 06 10 00 00 00 26 1b 00 e1 		| ship1*******&*** |
00 1c dc 0a 6d c0 73 68 69 70 32 00 bf 06 10 00 		| ****m*ship2***** |
00 00 26 28 00 e1 00 1c dc 0b c8 a0 73 68 69 70 		| **&(********ship |
33 00 40 00 00 00 		| 3*@*** |

Sprite 226 is the entire set of interceptors (shiplist); Sprite 225 represents a single one (with the data about weapons, etc).

Changing "ship3" to "ship4" (code change: a0 73 68 69 70 33 to a0 73 68 69 70 34) has the Interceptor #5 show up in the 4-ship launch queue, instead of #4.

However, presuming I can't just unilaterally increase the size of this code section, I don't think I am able to add a full line of code to a 96-byte function that puts together the sprite, which is what would be necessary to add a 5th interceptor to the UI.

So close, only to hit this wall. Anyone have any ideas or suggestions?

#10
Drakous79

Drakous79

    Drak

  • Supporter
  • PipPipPip
  • 843 posts
Nice and amazing find!

ActionScript involved makes it more complicating, especially for someone like me without proper knowledge. Would be of no help I fear.

Seeing what is repeated, this line may be long 22 bytes:
<PlaceObject2 idref='225' name='ship1' depth='14' matrix='t7041,2199'/>
bf 06 10 00 00 00 26
0e - depth='14'
00
e1 - idref='225'
00
1c dc 09 12 e0 - matrix='t7041,2199' ?
73 68 69 70 31 - name='ship1'
00

Without an option to adjust script's size, you would have to find some AS loop and its bytecode and try to rewrite the code. Also would be great to know, where is sprite's height, width or scale defined, in case of clipping issues. Matrix seems like X,Y coordinates. Dunno about depth (+13).




Page loaded in: 0.788 seconds