Aller au contenu

Photo

GUI editing


  • Veuillez vous connecter pour répondre
16 réponses à ce sujet

#1
Wybourne

Wybourne
  • Members
  • 9 messages
The GUI is handled by Scaleform, in the files ending in .gfx in core\\guiexport.erf. These files are optimised Flash swf files or something like that. The don't know if there is a tool to decompile to the Flash source files (.fla) from these files, even with Scaleform. It would be nice if we could get that, because I am fairly certain the names of the files are hardcoded into DAOrigins.exe, so we have to override these files in order to customize the GUI.

Now the good news: .swf files are usually valid .gfx files, so you can rename x.swf to x.gfx. I know you can't use certain features, but I have no idea what features we can't use. I know you have to use ActionScript 2.0 instead of 3.0.

Now more bad news: maybe the ActionScript is in a different format in the gfx files, as this swfc code generates a swf file which works in a browser, but doesn't work in game. I compiled this, renamed it quickbar.gfx, and put that file in my AddIns\\(module_name)\\override folder:

.flash filename="action.swf" bbox=300x300 fps=50

.box mybox color=blue fill=green width=100 height=100
.put mybox

.frame 1
.action:
_root.angle += 0.05;
mybox._x = 100*Math.cos(_root.angle)+100;
mybox._y = 100*Math.sin(_root.angle)+100;
.end
.frame 2
.action:
gotoFrame(0);
Play();
.end
.frame 3
.end


This is the result: http://img689.images...09112016193.jpg
Which from the image, looks like it does exactly what it's supposed to do: replace the toolbar with a most functional square. However, it doesn't move around as the ActionScript commands.

Modifié par Wybourne, 21 novembre 2009 - 12:26 .


#2
Qkrch

Qkrch
  • Members
  • 128 messages
Why don't you try with a simple flash animation, instead of a scripted one?



Maybe what it doesn't allow is scripted animation :D

#3
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
Dragon Age's GFx files aren't 100% standard SWF files. Although they're Flash 8 AS 2, they have some non-standard tags like ones for loading textures and specifying the UI resource name (apparently). Also they have some data blocks past the end-tag.

Look up sothink or "flare", but even then, good luck. Might need to define some intrinsics, but I've just been editing the p-code itself.

Modifié par FollowTheGourd, 21 novembre 2009 - 02:36 .


#4
Wybourne

Wybourne
  • Members
  • 9 messages
Oops, I think "decompile" is the right word, not "extract." >_> Edited the opening post to fix that.

Qkrch, I tried your suggestion to see if it works, and it did. This is good to know because now we know that the movie is actually played, and the frames past 1 not ignored.

Modifié par Wybourne, 21 novembre 2009 - 12:24 .


#5
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
Still, that's strange, the GFx files are full of scripted commands like that... gotoAndPlay everywhere. Edit: if you want to see what the GFx files are "really" like, just download my mod - I left it decompressed and with the SWF header. Edit2: I'm not really a flash designer - which is probably obvious - just one that was annoyed with the UI.

Modifié par FollowTheGourd, 21 novembre 2009 - 04:37 .


#6
DonTalone

DonTalone
  • Members
  • 4 messages
I have a question then: Is it only the .gfx files in the guiexport.erf that are needed to edit the gui or are there other files as well?

Because they don't look like very big in size, so mabye there's an opportunity to provide the community with an decompiled package of these resources... If there is a free programm to do it

#7
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
That's possible, I guess... but I don't know how useful it would be. If you just use "flare" which is free (by the same guy who wrote "flasm"), you can see the ActionScript. Sothink is better since it gives you a better structured view of it, but it's commercial software (not that much more expensive than Dragon Age was, though). The ActionScript you get out isn't going to compile though - it probably needs cleaning up, but even then there's weird stuff like "Mouse.LEFT", which is why I thought it might need some intrinsics... at least I don't see how that's a standard property.

At least AS 2.0 p-code isn't too complicated, so there's always that route if you just want to modify some of the pre-existing GUI. I don't know if there's much point in trying to create a GUI from scratch, since you'll probably have to clobber another GUI file to get it loaded by the game, and even then the communication between the game and your GUI is pretty much stuck with the interactions that the engine already expects.

Just use "flare" by Igor Kogan at www.nowrap.de/flare.html if you want to see a wax ball of ActionScript... but read below on how to get the file into a useful format first.

Here's what I wrote elsewhere a while ago:

The GFx files come in this binary file format: "[magic - 3 bytes][flash version - 1 byte][decompressed file size up to the SWF-end tag's data block in bytes - 4 bytes][compressed data until end of file]".

First you probably need to change "magic" from CFX to CWS, then use a program like "Swifty decompress" to inflate the file, or write your own using zlib. Depending on how you decompressed it, you may then need to change "magic" again to FWS to indicate it's no longer compressed. Some programs can handle it while compressed, some don't. But there is data past the SWF-end tag, which is *VERY* non-standard as far as a I know, and the size field in the SWF header doesn't include it, so again you have to be careful of not corrupting the end of the file.

At that point you can rename the extension from .gfx to .swf because certain SWF programs will refuse to handle files with a different extension, but you still need to keep the above issues in mind.

Now you should be able to more easily do stuff with it [snip rest...]. There are free tools out there like swftools, sswf, flasm, and flare that can help you edit and understand these files. Swftools has a Font2SWF tool which you may find useful, and maybe sswf has some tools for that too. There are commercial tools as well.

Just be careful about editing the file, since it is non-standard and some tools will choke on it or corrupt the file. E.g., the SWiX SWF editor somehow changes the GFx files so they're unusable in game. Some of the work involved here comes in creating your own tools to change things without messing up the file for the game, or adapting things to do the job.


Modifié par FollowTheGourd, 21 novembre 2009 - 01:57 .


#8
Qkrch

Qkrch
  • Members
  • 128 messages

Wybourne wrote...

Qkrch, I tried your suggestion to see if it works, and it did. This is good to know because now we know that the movie is actually played, and the frames past 1 not ignored.


Cool! I don't know anything about DA UI editing, i always heard that it was locked.. but reading your post I guessed that the locked stuff is just to add new UI screens, right? Anyway we could still use space for them in new modules.

And well, i've been "flashing" since I got my first pentium.. I've checked nothing of this you're talking... but the real problem may not be in the loop(), play(), etc etc... but the commands that buttons use, for example: those scripts that make the hotbar drag/drop or those callbacks used in the Veil transform UI or the final battle gather units UI, these two would be interesting...as we could see if the UI allows to simply call a script from our module.

Otherwise.. we could always buy that program... (lol)

#9
CID-78

CID-78
  • Members
  • 1 124 messages
well for you GUI guys here is things i would like to get my hand on.



*a GUI which only bringup the facegen tool of the chargen.

*a Dynamic chargen GUI which adampt to a .2da in number of races, classes and origins.

#10
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
[quote]CID-78 wrote...
*a GUI which only bringup the facegen tool of the chargen.
[/quote]
Probably possible (I haven't looked at it yet), but again there's the problem of what other GUI you want to sacrifice for it.

[quote]
*a Dynamic chargen GUI which adampt to a .2da in number of races, classes and origins.[/quote]
[/quote]
I don't think that's possible to do from the GUI alone, unless there's support for it in the engine or scripting framework. Maybe you can get around it on the GUI end with "getURL" trickery, but we have almost no access to the GUI from scripting (and vice versa), and I think we'd need more support exposed from the engine, or at least a better explanation somewhere of how to access its internals from the GUI. So far, I only know what I see used in the ActionScript, and that's probably not enough to start doing something drastically different.

Again I haven't looked at the chargen GUI, but that's going on the assumption that its data is hardcoded like I'm reading from your post.

Modifié par FollowTheGourd, 21 novembre 2009 - 04:38 .


#11
CID-78

CID-78
  • Members
  • 1 124 messages
I am not sure the data exist in .2da files but if it's read from those .2da's and in what sense the hardcode comes in place i don't know. but it would be good with someone that has knowledge about THe GUI to investigate. I have only played with the dascript events and i think i can do a work around but it won't be looking as good as a full GUI solution.

#12
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
Not to get anybody's hopes up, but I just found this pre-existing way of getting access to 2DAs from the GUI:
static function Get2DAValue(a_n2DA, a_nRow, a_nColumn) among other 2DA commands in the ActionScript (not DAScript) class ExternalCommands. That eventually calls getURL with an fscommand.

It still looks like you're limited to a hardcoded table of 2DAs, but I guess that's something. I don't know how much of them are even proper 2DAs, but there are apparently quite a lot available... I'd have posted them if I knew how to contain them within a box or something like on the old forums.

Modifié par FollowTheGourd, 22 novembre 2009 - 04:23 .


#13
CID-78

CID-78
  • Members
  • 1 124 messages
so can you loop over that function until it return a bad value and make a dynamic GUI. that's all that is needed. the .2da layout must be hardcoded but not it's size or values.

#14
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
Yep, but you'd probably need to redesign the GUI itself to better accommodate a list of entries if it previously assumed a fixed maximum size.

#15
Wybourne

Wybourne
  • Members
  • 9 messages
For RECORDHEADER(long), does the 32 bit field add to the length in the 16 bit field? Edit: I'm guessing it doesn't, because when I do that I get a bunch of tags with numbers in the thousands. Edit again: well, actually, when I don't do that, a bunch of tags have lengths that could fit in RECORDHEADER(short)...But at least all the tags so far make sense this way... >_>

Modifié par Wybourne, 22 novembre 2009 - 10:45 .


#16
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages

Wybourne wrote...

For RECORDHEADER(long), does the 32 bit field add to the length in the 16 bit field? Edit: I'm guessing it doesn't, because when I do that I get a bunch of tags with numbers in the thousands. Edit again: well, actually, when I don't do that, a bunch of tags have lengths that could fit in RECORDHEADER(short)...But at least all the tags so far make sense this way... >_>


You never add those two fields.

Are you taking little-endian format into account when you're trying to get the tag ID or size? I take it you're looking at Adobe's SWF file format PDF.

If it's a short tag (< 63 bytes of data), then there is no 32 bit field on disk (i.e., you'd be reading the data payload instead of the tag length info if you tried reading the next four bytes).

Edit: What you could be seeing is the short's size says 63 decimal and then the 32 bit field has a value less than 63. Technically I guess it could do that without breaking anything.

The tag is contained in the upper 10 bits of the short and the length is in the lower 6 bits. If the length *here* is 63 decimal, then you have to look at the 32 bit field for the actual length. Unlike other bitfields in the SWF format, you have to read the short in little-endian format instead of as just another sequence of bytes.

The non-standard tags are 1000 and 1001, and then there's some more after the SWF end-tag.

Tag 1000 seems to define the resource name "e.g., conversation for conversation.gfx", and tag 1001 seems to define DDS textures to use (which are further defined in XML files cutting out pieces in a texture atlas), which seem to be filled in a defineshape and also usable by a pseudo "img://" uri in their ActionScript MovieUtils (IIRC) class (but I'm not sure off-hand if that requires them to be defined upfront).

There's also a GUI framework that's used, but I'm not sure how much you have to use of that or how much is just the CLIK library or something else. But usually things seem to happen in the StartScene function, where the main clip does some stuff and assigns initialization callbacks to the other clips.

But if you have sswf installed, swf_dump should also show you the tags (although it's a bit out of date, I found it's format better than the swftools dump program).

Modifié par FollowTheGourd, 24 novembre 2009 - 12:45 .


#17
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
In case somebody finds this thread useful now or in the future, I'll add to what I wrote above: the GUI isn't limited to the 2DAs hardcoded into the table in the ActionScript class _2DA. The a_n2DA row is just the ID of the 2DA in M2DA_base, which you can extend as an M2DA and add your own tables to even. It's not a surprise, but at least it's confirmation that it's not limited in that respect.

However, for some reason right now I can't get the CRC32 values of 2DA column labels to match the values hardcoded in the GUI, but there's another function Get2DAValueByColumnName which accepts a normal label name instead - which I assume is slower. So there's still always that way of doing it.

Reading the DragonAge.ini file is another story, though. Although you can access your own sections and their settings using DAScript, the GUI is much more limited. It can access the values that  the game seems to expect to be there. For example you can get the gamma setting through ExternalCommands.GetValue("ClientOptions.VideoOptions.Gamma"). Trying to read your own settings, whether they're in a new INI section or not returns undefined. Trying to "cache" your own custom setting by first reading it through DAScript still doesn't let the GUI see it either.

This is probably better as wiki material, but editing the GUI needs a more comprehensive write-up before dribs of information like this really have a place there.

Modifié par FollowTheGourd, 02 décembre 2009 - 02:57 .