-
Posts
165 -
Joined
-
Last visited
Everything posted by XMarksTheSpot
-
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
There's no explicit compression for the Flash files. I think what you're seeing is caused by the way PatchUPK handles object replacements. Instead of changing the target object directly PatchUPK will create an altered version using the replacement data and append it to the UPK file while also updating the UPK's internal references to point to the new object. This means every time you perform a PatchUPK operation you'll end up with another version of your target object while leaving the original target object intact. This explains why you can still find the original data in the original location with a hex editor, but it's dead weight by now. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
Cont'd from Show Soldier XP mod page discussion. Yes and no. An ActionScript class is embedded in a DoInitAction SWF tag, and as with any tag it has a header section of its own which specifies its total byte size (sans header). On the byte level a DoInitAction tag is typically headed by 6 bytes, the first two of those declaring the tag type and the other 4 specifying the tag size. For instance, FF 0E F7 14 00 00 would be a DoInitAction tag which would be 0x14F7 (body) + 0x6 (header) bytes in size. For more information of Flash file anatomy I can refer you to Adobe's SWF File Format Specification document, the go-to resource if you want to deconstruct Flash files on the binary level. So you cannot simply replace a chunk of code with a larger one without also adjusting the tag header (in addition to the global GFx file header). Thankfully JPEXS does that automatically for you if you use its byte code editing functionality. As for the 'pointers or mem sizes' remark, ActionScript byte code also makes use of absolute jump offsets for control flow statements. So if you change a section of code in isolation you'll invalidate all jump statements after that. Fortunately, again, JPEXS re-calculates offsets automatically (using labels) so you don't have to worry about this. The general rule of thumb when editing ActionScript is to create a hex replacement that encompasses the whole tag from head to toe to capture the changed header as well as any modified jump offsets and other assorted changes on the byte level throughout the whole class. Basically, yes. While JPEXS has nice editing capabilities for many components of a Flash file it is not really intended for content creation. You can modify existing tags and even create new ones (e.g. new DefineShape and DefineSprite tags), but there's no user-friendly graphical editor to support this, you're going to have to punch in lots of numbers manually and for that you'll need to be intimately familiar with how vector shapes are defined in SWF files. Basically you wouldn't want to edit graphics using JPEXS :smile: What you can do though - and what I have done before - is to create your graphics in a Flash authoring program (Adobe Flash would be the obvious choice if you have access to it) or similar software that can create SWF files and copy over the relevant shapes and sprites. A bit of manual editing (e.g. using JPEXS) still remains necessary to fit the new tags into the existing hierarchy as tags are referred to by unique character IDs and it's very likely your injected tags' IDs would clash with existing ones. I can help with creating Flash-based vector graphics (like the proof-of-concept I posted), if you want. About your remark to patch in a whole SWF file, I'd advise against that as, although technically feasible, it's basically overkill for what you want to do. I think it's better to compartmentalize your changes so you can apply them separately. Still, you'll run into compatibility issues anyway, for instance two size-altering modifications will need to adjust the GFX header and there currently is no automation for that (like there is for UPK objects). Furthermore the issue of unique character IDs remains a stumbling block when multiple mods try to introduce new tags (for new graphics or scripts, for instance), so you'll invariably have to work off of other people's versions to create compatible versions. That's why my UFO health display mod has three separate versions for EU, EW and LW. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
Lovely :) As a general tip, the cyan shade used throughout the game uses the hex color value #67E8ED - I've used that so much I know it by heart by now ;) -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
Nice job, I like the minimalist design of the icons. If I had to nag, the empty space along the left and right edges of the formation images bugs me. I think it would look nicer if the formation would be aligned like the commanding/promotion symbol (and also so the 'Commanding' string and soldier name's left edge are flush). I've had a look at your images, I think you could slim them down to 16x24 to remove the dead space. If you need more fine-control you can always make the images larger (like double dimensions, 32x48) and shrink them down using the width/height attributes of the img tag you injected. As for the color choice, not a fan of the white-on-cyan which gets overridden by the yellow color transform on commanding/promotable soldiers anyway, so why not go cyan-on-cyan as well? You could also make the smaller dots have less alpha to make the bigger dot pop more (similar to like the class name text field uses 50% opacity). I'm a bit of a perfectionist when it comes to pixel-pushing, so, sorry about the nagging :) Keep on rolling :thumbsup: -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
Right, textures are required to have dimensions that are powers of two, e.g. 32x128, 64x64, 1024x512, etc. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
No idea, check the log? Maybe the filename of your image contains illegal characters or something. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
That depends on what you mean by 'custom graphics'. If you're talking about the game's UI you see various different elements in play there, like vector shapes (mostly borders and the like), raster images (for instance icons), text fields, and so on, all linked together using timelines (i.e. animations) and scripts. If you're specifically referring to the paragraph about dropping images (i.e. textures) into a UPK so you can reference them using "img://..." paths, you can do that using the Unreal Development Kit. There's a bit of information on the wiki about that. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
I don't think it's possible using HTML as Flash's support for that is rather limited. You could apply some dynamic tinting via ActionScript, but using the current setup you'd tint the text field as a whole, not individual sections of it. A more involved approach would be to do what I did for the soldier stats in the barracks list, i.e. to basically create a bunch of separate icon sprite-and-text field pairs and place them at the top of the screen. This is quite a bit more work than injecting a bit of HTML markup into an existing text field, mind you ;) A more straightforward option would be to simply create your own images and put them in a separate UPK, like I mentioned earlier. Technically you could place them in LongWar.upk if you wanted, but re-distribution of that file would be a concern :) -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
How about using images in place of the class names? You can use HTML <img> tags for that purpose, like so: <img src='img:///LongWar.ClassIcons.sniper' height='16' width='16'> Here's the list of available class icon path strings used in Long War: This is for example how we got the little interceptor/firestorm icons into the hangar ship list menu. You can also provide images of your own if you put them in a new UPK file and edit a few INI files to make it load in the appropriate places (like the strategy game). -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
You don't. Rather you use the Edit function of JPEXS' byte code editor and simply change the line Push "text" register2to Push "htmlText" register2Upon hitting Save JPEXS will do the necessary byte code re-compilation (which includes automatically adjusting jump offsets among a few other things). I think your question stems from the observation that even though the byte code editor displays string literals to reference class/function/variable names the accompanying byte code doesn't show any string data for the most part. This is because these string literals are (as a result of the original export/compilation process) defined once at the beginning of the script (the very first line preceded by the ConstantPool opcode) and later on are referenced via an index into that list. The implication of this is that you could change that index variable to reference a different string (and by extension a different class/function/variable), but this approach is overcomplicating things as JPEXS can determine that automatically. The only limitation there is that if no matching string is defined in the constant pool JPEXS will introduce an actual string literal in place of an index lookup. Which is not a bad thing at all, since adding a new string to the constant pool would amount to pretty much the same result. The general rule of thumb when trying to keep file size increases minimal is to add new names to the constant pool for elements that you intend to use multiple times, whereas if you only want to use a new string identifier only once you simply inline it. Yes, PatchUPK only cares about Unreal objects, it is not aware about any script class hierarchies inside SwfMovie objects (which would require a completely different parsing approach as those files are a separate type of document altogether). -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
It's gfxSoldierList.SoldierList. If in doubt, open the UPK file in UE Explorer and look for the SwfMovie in question. -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
There's a multiline property for that purpose, but from what I remember this'll make the text field fixed-width, so you'll want to enlarge its horizontal bounds along with it. To make use of HTML formatting the html property of the text field needs to be set to true and the htmlText property needs to be used for setting text instead of the plain text property. The latter means that you'll need to go into the SoldierList ActionScript class and modify the SetSoldierCountLabel() method which only makes use of the text property: function SetSoldierCountLabel(label) { this.soldierCount.text = label; this.soldierCount._visible = true; } A few notes about editing ActionScript code using JPEXS: First off, while JPEXS displays a nice decompiled view of the ActionScript code its actually reconstructed from pre-compiled byte code (similar to UnrealScript) and as such some measure of information got lost in the process. Most notably among that is that local variables have lost their names and are only referred to by numbered local memory registers (displayed as _loc3_, _loc4_ and so on in the ActionScript source view), some of which often typically fulfill special purposes, e.g. registers 1 and 2 refer to the keywords this and super respectively. Second, even though there's an Edit button for the ActionScript source view I highly advise against using it (as does JPEXS itself by popping up a warning dialog). The main strength of the tool lies in decompiling ActionScript byte code, not recompiling, and more often than not editing like this will fail. The most reliable option is to edit the byte code directly which is displayed in an ASM-like readable format in a separate editor pane next to the ActionScript source view. Editing the byte code source takes some getting used to due to its stack-based nature. Simple alterations like changing a numerical value or a string are straightforward enough though. On the topic of introducing size changes, there's basically two operations that need to be performed to get those working. On the UPK side the Flash file as a whole is wrapped in a so-called SwfMovie object which typically has the same name as the Flash file itself and is put into a package that also has the same name but with a "gfx" prefix. As an example the SoldierList movie object would be found inside the gfxSoldierList package (in turn being inside UICollection_Strategy_SF.upk). As with UnrealScript objects the UPK file needs to know about the total size of such a SwfMovie object and therefore the same resize patching rules apply (i.e. you can use PatchUPK's auto-resize feature to take care of that). The second operation requires a manual replacement, there's no automation for that. Basically a Flash file contains a short header section that always looks like this: First three bytes are the characters G F X, fourth byte holds miscellaneous bit flags and bytes 5 through 8 encode the total byte size of the Flash file in little endian format. Note that Toolboks replaces the first 3 bytes with the characters F W S in an attempt to make the file look like a standard Shockwave Flash file, but it's really a Scaleform-specific extension of the format, hence the GFX references throughout (as in Scaleform GFx like it's also called). Anyway, the SwfMovie object which wraps the Flash file also repeats these 4 size bytes right before the GFX header section. So, in addition to the automatic object resize you'll also need to add a secondary replacement that adjust the total Flash file size in those two places (which fortunately are spaced apart only by 4 bytes). As an example (in what basically amounts to a bit of hex math), if your original GFX file was 0x1234 = 4660 bytes in total the area around the header would likely look something similar to this: … 34 12 00 00 84 5F 07 00 34 12 00 00 … < size1 > < "GFX" > < size2 > If, through edits, you enlarged the file by, say, 0x56 = 86 bytes you'd end up with 0x1234 + 0x56 = 0x128A = 4746 bytes and your resulting AFTER block would need to look like: … 8A 12 00 00 84 5F 07 00 8A 12 00 00 … < size1 > < "GFX" > < size2 > That's basically the gist of resizing the GFX file as a whole. If you keep using JPEXS for editing the contents that's pretty much all you need to take care of, in addition to finding the before/after byte sequences corresponding to your changes - you wouldn't want to have the whole SwfMovie binary object in a PatchUPK mod file, though PatchUPK allows referencing separate binary files for replacements, at least for installation, the auto-generated uninstall file is a text file, as far as I remember, and that's pretty unwieldy for large objects. For a more involved example you can look at my Interception UFO Damage Display mod which modifies the Interception GFX file by introducing new sprite definitions and rewriting some ActionScript logic. Also feel free to keep asking about UI stuff, I'm always eager to help out prospective UI modders :smile: Also, sorry for yet another wall of text :sweat: -
How to resize and/or move UI elements?
XMarksTheSpot replied to SpazmoJones's topic in XCOM's Enemy Unknown
You mean the count display at the top of the barracks soldier list? From the looks of it this is a plain text field, albeit one which does not have its autoSize property set, so it won't grow automatically to accomodate different contents. To take a step back and explain a bit more, XCOM uses the Scaleform middleware for its UI, which basically allows embedding and interacting with Flash files in the game. Thankfully it is quite possible to extract these Flash-derived files from the game packages so you can have a look at them. Making changes to them is a bit more complicated though and ranges from single-byte edits to having to replace and/or resize large sections, depending on what you want to do. Fortunately enabling auto-sizing falls into the former category :smile: Generally you'll want to extract the Flash files from the relevant *.upk files, either by excising them manually or by using Toolboks, which can do that automatically for you. After extracting you can view the contents of the resulting Flash files using decompilers like JPEXS Free Flash Compiler. JPEXS also has limited editing capabilities which come in handy for making small to medium-sized adjustments. In the specific case of the barracks list you'll want to extract the corresponding Flash menu file from the UI_Collection_Strategy_SF.upk package file. If you used Toolboks to extract the Flash files you'll have to manually look through them to find the right one since Toolboks names the resulting files using only a number index corresponding to where the Flash file is located in the parent UPK file. The SoldierList file should be number 45, if I'm not mistaken. The soldier list menu itself is a composite of various sprites that serve different purposes - some provide (semi-)interactive elements (like text fields and scrollbars), others are purely visual (like borders and backgrounds). Some of those sprites are named which typically means that they are in some way connected to some ActionScript code (the Flash-specific scripting language). If you look through the sprites you'll notice one named SoldierList which makes up the bulk of the menu. Inside that sprite you'll see different objects being placed, one of which labeled soldierCount - that's the text field you're looking for. Going up the hierarchy again in JPEXS' tree view you'll see a different branch named texts under which all text fields used throughout the menu. The soldierList sprite references the text field with the numerical identifer 65 (the text field itself doesn't have a name identifier, only its instances when placed in a sprite). Selecting that text field entry in the tree will show a list of its properties, stuff like color #ff67e8ed or align left. However, JPEXS only displays the properties whose values differ from the default state (I think), that's why the autoSize property is nowhere to be found in the list. Nevertheless, you can edit the property via right-clicking the tree entry and choosing Raw Edit from the context menu which will display a more detailed tree view of the object properties. Sure enough, looking through that view you'll notice an entry labeled autoSize = false. Hitting the Edit button at the bottom of the screen let's you change that property (by way of a checkbox) after which you'll want to hit the Save button (where the Edit button was before) and finally save the whole file via the Save (or Save As... if you're so inclined) button in the File section of the ribbon menu around the top of the application window. The way text fields are defined in Flash files means that changing that autoSize property only changes a single byte in the whole file (a single bit even, to be more precise). So all that's left is to open the original Flash file and the JPEXS-altered one in a hex editor, finding that single changed byte (pro tip: search for the placeholder text which is set as the initialText property of the text field, i.e. that HTML-formatted stuff at the bottom of the basic properties view) and create a mod file for your preferred patcher tool (PatchUPK/PatcherGUI, I'm guessing) from the surrounding bytes. So, all in all a very straightforward one-byte fix to enable (horizontal) auto-sizing of a text field. Sorry for the wall of text, there is a bit of information about Flash editing on the wiki, but it's a bit outdated and doesn't go into details like text fields, so I tried to be comprehensive :smile: -
The most likely is a way as that was done for various DLC add-ons in the EU version which all come with a CookedPCConsole folder of their own. I have briefly looked into the Unreal Frontend utility for cooking/deploying content which seemed to have modes for DLC-style operations, but I couldn't really make sense of it :ermm: Not sure what's needed to make the base game recognize DLC-style content either, I think Amineri dug up some info about that here.
-
You're making good progress, Liquid, keep it up :thumbsup: Very much appreciated :) So I take it you're actually creating your map partially in the UDK? That would, indeed, be very handy, saves us from having to write a custom map editor ;)
-
Why don't you simply try and see for yourself? That's literally a single byte you need to change, you can even do that from within UE Explorer's buffer view.
-
I think this could be achieved by overriding GetMCPath() to point to a different SwfMovie, but there might be more to it than that, no idea. I guess you could try this by extracting one of the game's Flash files, put it in a different package, point to that via altered GetMCPath() and see if everything still works :) Note however that frequently SwfMovie objects are placed alongside other related objects (mainly Texture2D objects used in the movie file) in the same group. Not sure if this is a necessary precondition or just a by-product of the cooking process (or both).
-
I haven't attempted to create an all-new screen yet, but there's lots of information to be found about UE's Scaleform middleware implementation. Not too sure about how everything needs to be set up w.r.t. UnrealScript logic. All of XCOM's UI classes seem to extend one of several linker classes like UI_FxsScreen or UI_FxsPanel which are actors at their core. Those linker classes define (among other things) a GetMCPath() function which, I guess, returns the package path of the embedded SwfMovie object to which the class is supposed to be linked. GetMCPath()is a native function though, so since the actual logic behind it is not immediately visible it's hard to tell how and where the attached objects need to be put in order to be recognized properly. This is a bit of a headscratcher especially when considering that almost all of the SWF movie clips are dumped in collection packages (e.g. UICollection_Strategy_SF.upk) separate from the linked UnrealScript game logic classes.
-
Ooooh shiny! At first I thought you simply hacked in the unused message-of-the-day ticker functionality, but it looks like your discovery runs quite a bit deeper than that :) Great job! :thumbsup:
-
Instead of messing with UnrealScript logic a different approach would be to prevent certain UI components from being placed in the HUD directly in the embedded Scaleform GFX files. Here's a few instructions to get you started: grab a copy of Toolboks EW and extract GFX files from UICollection_Tactical_SF.upk (via Extract SWFs button inside Custom Mods tab)grab a copy of JPEXS Free Flash Decompiler and open the TacticalHUD file with it (should be named UICollection_Tactical_SF_23.swf)browse the list of sprite definitions and locate the TacticalHUD MC sprite:http://i.imgur.com/gBvWoXg.png observe how inside that sprite various sub-sprites are placed with descriptive names like theObjectivesList and theRadarMCswitch to Hex Dump view (in the File menu ribbon) and locate the corresponding DefineSprite entry:http://i.imgur.com/75rEXrr.png observe how selecting an element in the left-hand tree view will highlight the corresponding byte sequence in the right-hand hex viewopen UICollection_Tactical_SF.upk with a hex editor (like HxD) and locate the highlighted byte sequence (for instance using a text search for "theObjectivesList")select the highlighted sequence and use Edit -> Fill Selection... to replace the sequence with zero bytes:http://i.imgur.com/hDGyAlY.png et voilĂ , you now (deliberately) broke part of the HUD :smile:repeat for other sprites Note how the camera controls sprite (called MouseControls) is nowhere to be found inside the TacticalHUD MC sprite (or any other sprite for that matter). This is because the component is dynamically placed via ActionScript instead of being pre-placed and toggled on/off conditionally like the radar or objectives. One simple way to work around that is to garble the script identifier of the mouse controls sprite, like so: open the TacticalHUD file in JPEXS and locate the DefineSprite tag of the MouseControls sprite (id 370):http://i.imgur.com/rw1aMIA.png ignore the sprite tag and observe how it's followed by an ExportAssets tag - this is used to define the script identifierlocate the highlighted byte sequence using a hex editor and replace the name part with any other byte sequence (e.g. zero bytes or random characters)Now the script for dynamically attaching the mouse controls cannot find the corresponding sprite and therefore no such component will show up on the HUD. Enjoy!
-
I don't really know about proper debugging techniques, but double-checking your modifications is usually a good start when dealing with CTDs. For that purpose its helpful to check whether your modified function decompiles correctly in UE Explorer. If it doesn't a likely candidate for the error is mismatched jump offsets from control structures, i.e. if-then-else or while blocks. Both UE Explorer and UPK Modder can help with figuring out the proper offsets. Other than that, try adding your code modifications one line at a time to find any crashy statements in particular. Sorry that this is all rather general, but this is basically what I had to go through to get the few UnrealScript modifications working that I attempted :smile: Not sure what would require further in-depth debugging, maybe give a few more details?
-
If you're doing a resize operation the new function change is simply the old function change plus resize value (i.e. the total number of bytes changes). Even if you do no resizing the memory size may change and you can use the memory offset display of the editor pane to get the correct values for that. Basically if you have the complete function body in a before/after block and the end-of-script (EOS) token is singled out as the last line the memory size of the function is the memory position of the EOS token plus 1, like so:
-
Aye, collapse/expand all is in now :smile: Hope you don't use any symlink loops in your mod file hierarchy, that would surely break our simple tree view :wink:
-
Which context menu are you talking about? From within the editor? We currently don't have a context menu there. If you're talking about the context menu inside the project tree, reworking the modfile rename functionality a bit could serve the purpose of getting the file name to the clipboard. 'Search for this File' doesn't make much sense to me though in that context :confused: Ctrl+F will open a basic search dialog which allows to repeatedly search for a string to find all occurrences. There's no wildcard searching though and a major limitation is that the search functionality only extends to the currently expanded nodes, i.e. there's no deep searching the tree.
-
This can be easily achieved by replacing the tree component with an extended version found in an external library which I tried to avoid adding to the project so far to avoid unnecessary bloat. I went ahead and added that extra dependency just now, so the project tree and mod file editor now have native search support using Ctrl+F. The trade-off is that our so far pretty lightweight project grows by another 1.5 MB, ah well :smile: I'll leave it to Amineri to package the new JAR files and upload them to the drive folder since I don't have access to that :smile: