Jump to content


Photo

can weidu decompile scripts right from the bif ?


  • Please log in to reply
24 replies to this topic

#1 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 01 March 2003 - 12:30 PM

I'm doing a weidu interface for scripts (dialogs already covered).
My problem is that original scripts are still biffed. Is there any option (or would you implement one), which extracts a script (or other file) if it isn't in the override. Override should be the priority, if it isn't in the override, it could look around in chitin.key/biff. Just like the game does it.
If not, it isn't a problem, my tool could extract it, but i thought i would create less garbage if someone only wants to take a peek at a script, so a bcs wouldn't appear everytime in the override.
If there is any method already of doing what i asked for, please tell me.
Even if it is not completely automated: it can open a file from bif but wouldn't look in the override first.
thanks.
Avenger

#2 Dyara

Dyara
  • Member
  • 262 posts

Posted 01 March 2003 - 05:12 PM

WeiDU script.bcs --out C:\temp

would look for script.bcs in override or biff, decompile it and create the baf file in C:\temp (for example).

#3 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 02 March 2003 - 05:09 AM

Hmm, i wonder why i get so many trivial errors, i thought i downloaded weidu v110.
Two more problems:

Problem1: weidu doesn't recognise tokens starting with number (2daresref) when parsing my
action.ids, the ingame script compiler doesn't complain.

[ACTION] PARSE ERROR at line 224 column 29-36
Near Text: daResRef
syntax error
ERROR: problem printing script [d:\bg2\script compiler\compiled\01POOL1]: Parsing.Parse_error


Problem2: i didn't specify --text, yet weidu issued strref comments in the script
Avenger

#4 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 02 March 2003 - 06:53 AM

One more problem:
In our shoutids.ids file there was a line:

14 OUCH!

Weidu complained on this line and stopped decompiling :(
The game doesn't care about '!'

Well, not a big problem if you see the weidu output :)

Anyway, i've finished my weidu gui, you can try it.

http://www.dragonlan...lay;threadid=19
Avenger

#5 weimer

weimer
  • Member
  • 1569 posts

Posted 02 March 2003 - 12:23 PM

Yes, WeiDU can decompile BCS files from the BIFs. Example:

$ weidu jaheira.bcs

will produce jaheira.baf (from the override first or the bifs second) even if no jaheira.bcs is in the current directory.

WeiDU does not currently support custom action and trigger ids files that have keywords that start with numbers. I don't care much about the compiler distributed with the game -- can NI and the game engine itself handle such things?

WeiDU always produces comments in BAF files. However, the next version will let you use the --nocom switch to turn them all off.

The next version of WeiDU will allow !s in tokens.

#6 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 02 March 2003 - 01:05 PM

I didn't realise that the variable names were modified by us, sorry :)
I just thought you introduced some syntax checking recently.
But NI and the Game engine can handle it quite well. If the engine would choke on it, then it would be completely reasonable to forbid them.

We also got a custom trigger:
0x4034 DLHaveSpell(S:Spell*,S:LOCALS*,I:*HAVESPEL)
which is faking this one:
0x4034 GlobalGT(S:Name*,S:Area*,I:Value*)

Weidu apparently always uses the second prototype.
This in itself wouldn't be a problem, it is our fault :)
The problem is that WeiDU sticks the strings together for example a
GlobalGT("myvar","LOCALS",1)
would look like:
DLHaveSpell("LOCALSmyvar","",TWO)
I wouldn't complain if it produced:
DLHaveSpell("myvar","LOCALS",TWO)
Avenger

#7 weimer

weimer
  • Member
  • 1569 posts

Posted 02 March 2003 - 07:52 PM

Custom trigger: I was listing the "GLOBALmyvar" functions based on name, but I switched to doing it based on number to solve that problem.

Tokens that start with numbers: I would hate to have you give up on WeiDU because you are dead-set on using tokens that start with numbers ... but there is a reason that they are basically never used in programming languages (bonus points: name a programming language that allows you to start a variable or function name with the letter '2'). WeiDU's parsing would be dramatically complicated because there is no easy lexing rule to tell the difference between an integer and a token. Example: is "2a" the integer 2 followed by the token a, the token 2a, or the hex number 2a (= 42)?

#8 -avenger-

-avenger-
  • Guest

Posted 03 March 2003 - 05:26 AM

Nah, i don't insist on modifying this. I understand your motive, C is my native language.
I was just pondering why weidu doesn't work while I coded the GUI. Since it wasn't me who changed our action/trigger.ids, but Max, i had absolutely no idea why it doesn't work and whom to blame about it.
And I know I wasn't alone. It turned out that Sim had the same problem :)
So, it is fair enough if you don't implement that change, people just should know the rule, maybe a bit better error handling. (Near text daResRef isn't telling much.) What about telling: illegal character '2' before 'daResRef'.
Just an idea, i don't really want to push this.

And now, there is a new problem:
if i don't specify a --tlkout dialog.tlk option weidu silently leaves dialog.tlk untouched. It claims that it added x bytes and y entries to it, but in fact it didn't. Yes, i know i can always add the proper option, but it scared the s..t out of me. This appears just a simple 'not knowing the rules and not telling the truth' kind of problem too. :(

#9 weimer

weimer
  • Member
  • 1569 posts

Posted 03 March 2003 - 10:25 AM

Error reporting during parsing is actually a very tricky topic. If you did the same thing in a C program:

int main() { 
  int 2dathingy = 5; 
  return 0; 
}


... you wouldn't even get the column number or the nearby token. GCC gives the interesting result:

test.c: In function `main':
test.c:2: nondigits in number and not hexadecimal
test.c:2: nondigits in number and not hexadecimal
test.c:2: nondigits in number and not hexadecimal
test.c:2: nondigits in number and not hexadecimal
test.c:2: missing white space after number `2dathi'
test.c:2: parse error before `2dathi'


While MSVC gives:

test.c(2) : error C2059: syntax error : 'bad suffix on number'
test.c(2) : error C2143: syntax error : missing ';' before 'constant'
test.c(2) : error C2146: syntax error : missing ';' before identifier 'dathingy'
test.c(2) : error C2065: 'dathingy' : undeclared identifier


Even professional programs will not be able to say something like "hey, identifiers cannot start with numbers!". I cannot (using automatic tools) report the '2' by the time I am complaining about the 'dathingy' because it is the previous token (it was lexed as an integer constant) and only the text of the current token is kept for me. :-(

You are quite correct about the string-adding text. It is misleading. I have changed WeiDU locally so that it now gives messages like:

You did not specify '--tlkout dialog.tlk', so 1 strings were not saved.


Look for it in the next version.

#10 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 03 March 2003 - 10:50 AM

Ok, just make it (the daresref thingie) clear in the manual. (*Avenger pretends he read the WeiDU manual*)
Do you expect that anyone using WeiDU is aware of certain programming 'rules' ?
Well, WeiDU does quite well on improving programmer awareness of the average user. :P

I have learned it now, and if the user is wise enough to tick on WeiDU logging s/he will even see the parsing error (in my tool).

Btw, don't take my trivial bugreports as if they are about pricking (i don't suppose you take them),
i'm just a newbie (weidu) user who had to teach another program to handle WeiDU. Even the slightest misunderstanding between the two programs could be more fatal than interfacing a much more intelligent user.

Actually, Windows, the different versions of them, created some weird problems, apparently on WinXP and Win2000 one cannot issue a line like this:

system("\"d:\\bg2\\weidu.exe\" etc etc")

On Win98 it works though. (I needed to put the weidu path in apostrophes because of possible spaces in it). Such a tiny little difference could result in hours of extra coding.
Avenger

#11 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 04 March 2003 - 12:21 AM

OK, a more serious problem: it seems weidu can't decompile the SetTokenGlobal action.
This action got 3 strings in its prototype. You have to cut the first string in the .bcs into area/variable, the second string is a "token". If you ever implement tag checking, it should be a "valid tag".

And an idea:
You implemented action/trigger text parsing. Like AddJournal(@1000)
I suppose this could work in .dlg decompiling (exporting to .d) as well.
Avenger

#12 weimer

weimer
  • Member
  • 1569 posts

Posted 04 March 2003 - 09:26 AM

SetTokenGlobal -- I didn't know it was one of those. Here's my list:

 |  0x400F (*Global(S:Name.,S:Area.,I:Value.)*)
  |  0x4034 (*GlobalGT(S:Name.,S:Area.,I:Value.)*)
  |  0x4035 (*GlobalLT(S:Name.,S:Area.,I:Value.)*)
  |  30 (*SetGlobal(S:Name.,S:Area.,I:Value.)*)
  |  115 (*SetGlobalTimer(S:Name.,S:Area.,I:Time.GTimes)*)
  |  109 (*IncrementGlobal(S:Name.,S:Area.,I:Value.)*)
  |  246 (*CreateCreatureAtLocation(S:GLOBAL.,S:Area.,S:ResRef.)*)
  |  256 (*CreateItemGlobal(S:Global.,S:Area.,S:ResRef.)*)
  |  268 (* RealSetGlobalTimer(S:Name*,S:Area*,I:Time*GTimes) *)
  | 335 (* SetTokenGlobal(S:GLOBAL.,S:Area.,S:Token.) *)
      -> true

Let me know if there are any actions or triggers I am missing.

Your "handle strrefs in DLG triggers/actions when decompiling" is a lovely idea. Do you have a list of all actions/triggers that take strrefs?

#13 -Sim-

-Sim-
  • Guest

Posted 04 March 2003 - 10:05 AM

Strref parameters usually (if not always) specify I*StrRef. A quick search in NI reveals the following actions:

151 DisplayString(O:Object*,I:StrRef*)
173 AddJournalEntry(I:STRREF*,I:Type*JourType)
235 SetQuestDone(I:STRREF*)
247 SetToken(S:Token*,I:STRREF*)
262 DisplayStringNoName(O:Object*,I:StrRef*)
263 EraseJournalEntry(I:STRREF*)
269 DisplayStringHead(O:Object*,I:StrRef*)
288 SetName(I:STRREF*)
292 DisplayStringHeadOwner(S:Item*,I:STRREF*)
308 AddMapNote(P:Position*,I:StringRef*) (Exception to the rule, hehe)
311 DisplayStringWait(O:Object*,I:StrRef*)
320 SetPlayerSound(O:Object*,I:STRREF*,I:SlotNum*SNDSLOT)
328 RemoveMapNote(P:Position*,I:STRREF*)
342 DisplayStringHeadDead(O:Object*,I:StrRef*)
346 DisplayStringNoNameHead(O:Object*,I:StrRef*)

As for triggers, nothing appears in a search, and I doubt there are any using strrefs.

#14 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 04 March 2003 - 11:57 AM

IWD2 strref using actions:

151 DisplayString(O:Object*,I:StrRef*)
241 FloatMessage(O:Object*,I:STRREF*)
244 DeleteJournalEntry(I:Strref)
245 JournalEntryDone(I:Strref)
266 DisplayMessage(I:StrRef*)
275 SaveGame(I:STRREF*)
312 SetApparentNameSTRREF(O:Object*,I:StrRef*)
313 SetRegularNameSTRREF(O:Object*,I:StrRef*)
314 EndGame(I:StrRef*)
Avenger

#15 -jcompton-

-jcompton-
  • Guest

Posted 04 March 2003 - 02:28 PM

Ah, you have IWD2, Avenger? I don't suppose you'd like to, say, take apart and document the IWD2 .gam format so Wes can make joinable NPCs work properly in IWG2, would you? :)

#16 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 06 March 2003 - 08:08 AM

I saw only the starting iwd2 gamefile, which is suprisingly the same as an emptied BG2 file :)

I didn't care much about the game produced files because i didn't intend to create a save game editor.
Avenger

#17 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 06 March 2003 - 10:46 AM

More info on IWD2 scripting:

1.
There is an action called SpellCastEffect (#289)
It has 3 string arguments.
As you know .bcs files got only 2 string storages, so 3 strings always mean 2 strings are concatenated somehow.
Usually they stick area+variable strings together.
This is true for ALL BG2 actions/triggers. If there are 3 strings, the first 2 strings, which are area+variable are stuck together to form the first string.
Sadly this isn't so simple in IWD2:
In some newer IWD2 actions sadly they concatenate them with a : (comma) between them, but still store them in the first string slot.
In the abovementioned action, they concatenate the last 2 strings (sound1, sound2) and store it in the second string slot.
So, please in the case of #289 IWD2 action decompile the last 2 strings from the second .bcs string slot and concatenate them using a comma.
An example: 41cnatew.bcs
the action--> 289 SpellCastEffect(O:Source*,S:Voice*,S:Sound1*,S:Sound2*, I:Animation*sceffect, I:Speed*, I:Sequence*Sequence)
More actions using 3 or more string arguments:
243 IncrementGlobalOnce(S:String1*,S:String2*,S:String3*,S:String4*,I:Value*)
248 GlobalBitGlobal(S:String1*,S:String2*,S:String3*,S:String4*,I:Mode*BitMode)
These will surely store 2-2 strings separated by commas (not tested)


2. for some weird reason there is an attstyl and an attstyle file in IWD2's chitin.key
The attackedby trigger has attstyle written in it, yet, attstyle is a crippled file.
I have absolutely no idea how could it be so screwed up, people are adviced to change attstyle in their trigger.ids if they got compile errors with the abovementioned trigger.
fixed trigger.ids entry-->0x0002 AttackedBy(O:Object*,I:Style*ATTSTYL)
Avenger

#18 -Sim-

-Sim-
  • Guest

Posted 06 March 2003 - 01:48 PM

248 GlobalBitGlobal(S:String1*,S:String2*,S:String3*,S:String4*,I:Mode*BitMode)

Has anyone got a clue what BitGlobals do? Because IWD1's scripts were full of them, and I can't for the life of me figure out why.

#19 weimer

weimer
  • Member
  • 1569 posts

Posted 07 March 2003 - 06:20 PM

All STRREF and STRINGREF actions now have nice comments.

As per Avenger's suggestion, --trans now looks inside DO actions as well. For example, weidu --trans --nocom jaheira.dlg will give you:

IF ~~ THEN BEGIN 14
  SAY @51
  IF ~~ THEN UNSOLVED_JOURNAL @52 EXIT                                          
END

...

IF ~~ THEN BEGIN 30
  SAY @82
  IF ~~ THEN DO ~EraseJournalEntry(@52)
AddexperienceParty(3000)
JoinParty()
~ EXIT                                                                          
END

with jaheira.tra containing:

@51  = ~It would be best to face the culprit another day on our own terms, so go and be quick. We must free ourselves soon.~                                    
@52  = ~Find a way to release Jaheira from her cell.

Jaheira is kept captive in the same room that I was, in a cage closed with a magical lock.  It does not look as if it can be picked.  Perhaps there is a key elsewhere in the dungeon.~     
...
@82  = ~No matter, as I will not be put off so easy. I will join, and follow as you see fit. See that we do not stray too far afield, lest I regret my decision. ~      


The IWD2 three-strings are low priority for me until someone jumps out and says that they really care.

#20 Avenger_teambg

Avenger_teambg
  • Member
  • 604 posts

Posted 08 March 2003 - 06:16 AM

Actually I really really care only about the SetTokenGlobal thingie (in bg2).
IWD2 has low priority for me.
I just thought you want to support it more, since you work on IWG2 :)
Avenger