Author Topic: Info about the field scripting language goes here.  (Read 25291 times)

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
This is going to be an expansive section of Gears and so it's nice to start a new topic and keep the script-related here.

Now, this is a sample of how I'm documenting each opcode. I think this is the most elegent solution.



Now, if you guys want you can take a line from the opcode marix in Gears and assist me by posting discovered arguments in something like this style here. I'll pop it into Gears. If you can think of something more elegent than this, let me know before we hae 128 of the little boogers decypered only to find some really key information we should of included...

For example should WINDOW say the following?
WINDOW (id=00 x=0000 y=0000 h=0000 w=0000)
-----

Now, terrence, because you have had more play time with script logics (I've been working on more of the cosmetic aspects of the language) Can you tell me how memory management works? Is there a protected array in memory that the script language uses for storing variables? Does it has free reign over the the PSX's memory. I would think the kernel will allow for a degree of protection.

Also, are there flags? Are these bools different from the memory array?

I guess memory management should be the first thing to work out.

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #1 on: 2004-07-12 01:06:13 »
Just looking at it... I'm not sure it has any private addresses.  It frequently accesses standard FF7 variables, which means it has full access to the save block.  Outside of that, it's difficult to say... most scripts are self-contained, and what variables they need are always localised around that area's plot variables.

Now, stuff like objects on the field and setting IDs and direction... that's slightly different.  But it's not something you're going to see from the scripting language itself; tracing it in memory or looking at the disassembled EXE (and hoping you can track down the script interpreter) is pretty much best bet there.

Does that answer your question?  I'm not sure how some opcodes reference the same bytes... sometimes there's definitive differences in the exact way they interpret it... the Random opcode is a good example of that.

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #2 on: 2004-07-12 03:14:31 »
Random discovery, I'd thought I'd post it here... It's just a note

First a little vocabulary

SCRIPT: The logic of the field file

DIALOG: The actual "words" spoken in windows. This is in a seprite section

ENTITY: An object that's in the field, it can be a person, save point, materia, the player, or even an abitrary place.

PC: The player

From browsing the script file, there seems to be two scripts associated with an entity. One is an initalization script that places the entity on the map, and second is a script that does the interaction with the PC.

For example XYZI is the inital XYZ location of the entity. I have found that always is in the init script (It always seems to be the first one assiciated with that entity)

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #3 on: 2004-07-12 11:46:33 »
You may also note that the REQ series of commands (REQ, REQSW, REQEW, PREQ, PRQSW, PRQEW) are meant to call different scripts.  It's used, for example, for conversations: like talking to a boy, then answering a question, and then suddenly one of Cloud's scripts is referenced to do an animation and state a reply, and then it comes back to the boy, who might say something, and then reference *another* of Cloud's scripts, etc., etc.

So far, although all REQ commands are in the format 'ab cd' with arguments, I only know the 'd': it's the *number* of the script associated with the object being called.  How 'cab' refers to the proper object, I'm not sure; I've not seen a concrete relation between the two yet.  It may be something that is best left to the script dumper to work out, if it can be modified to do it.

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #4 on: 2004-07-12 12:26:02 »
Heh, I was just gonna start in on those. I have to learn not to read too much into the opcode names.

REQ?

Request?

Request what? Request Stored Word?

Cyberman

  • *
  • Posts: 1572
    • View Profile
Info about the field scripting language goes here.
« Reply #5 on: 2004-07-12 18:47:37 »
Hmmm I think it might be refered to as a CALL to subroutine on an object.

in C++ you might be able to refer to it as

<object>.<subroutine>(Parameters)

This infers some OOP in the scripting language. Perhaps shifting to C++ to describe it will be better for me (mumbles softly).  However it does make sense now that I think about it. :)

I would describe something like that as a subroutine on an object personally.

Cyb

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #6 on: 2004-07-13 14:37:58 »
After going through some of the other minigames, out of curiousity, it seems that many of the commands do switch that first byte, just like Random does.  Here's a few more commands that I'm guessing at:

MPARA(bh, wid, vid, bl)
  Takes what's stored in (bh)[bl] and assigns it to variable VID in the soon to be created window of id (wid).  Used to print up variables in message boxes.

MPRA2(bh, wid, vid, bl(2))
  Takes what's stored in the SWord(bh)[bl] and does the same as MPara.

PLUS2(bhs, bl, const(2))
  Adds the number in const to SWord(bh)[bl]; bh's nibbles are switched, just like randoms.

DEC(bhs, bl)
  Decreases the number stored in (bh)[bl], nibbles switched again.  No idea what happens when it hits 0.

SET-WORD(bhs, bl, const(2))
  Went over it before, but this is the more formal definition: stores const in SWord(bh)[bl], nibbles switched.

That's about the size of it for now.  If I see anything else interesting, I'll add to it.

 ===============

Edit: More information on variables:

(10)[00] refers to 00DB1EC4 (v1.0?), and this byte is the plot address I talked about earlier.
(20)[00] refers to the same address.  The only difference is that the (20) is associated with words rather than bytes.

(50)[00] refers to 00CB2B80 (v1.0?), and is the start of the temporary variables set aside for scripting (so they do have private addresses...)  They's overwriten very often though.
(60)[00] refers to 00CB2B80, as usual, but relates to words over bytes.

I *think* (don't have concrete evidence yet but...) that the 1/2/5/6 byte doesn't count with regards to absolute addresses: it just relates to what section we need to look at and what's to be expected.  (22)[58] should be offset 0x258 from 00DB1EC4, for example, and is exactly the same as (12)[58] with relates to what address we're looking at.

Keep in mind that, as stated, certain opcodes will reverse the first byte, so 62 01 will be referred to as 26 01.  I've already noted a couple of opcodes that do this.

 ===============

2nd Edit: Update on variables.

Okay, forget what I said.  It's more complicated.  Much more complicated.

Right, we've got *5* numbers.  0, 1, 2, 5 and 6.  They mean the following:
0: Constant
1: Permenant Plot Variable (Byte)
2: Permenant Plot Variable (Word)
5: Temporary Variable (Byte)
6: Temporary Variable (Word)

Now, here's where it gets... well... fun.  Let's look at a couple of sample commands.

81 62 08 00 00: SET-WORD (62, 08, 00, 00).  So, what does this mean?
It means: (6)[08] = (2)[00].
The first byte tells us 'destination type' and 'source type'.
The second byte tells us the 'destination offset'.
The third byte tells us the 'source offset' or 'constant'.
In this case, the destination is (6), so it's a temporary word variable, and the [08] means it's at Offset 0x08 in the temporary block.
The source is (2), so it's a permenant word variable, and the [00] tells us it's in Offset 0x00, which happens to point to the Plot Progression Variable.

So all in all, we've just moved the contents of a variable to another variable.

Even more fun:
88 62 08 AD 00: MINUS2 (62, 08, AD, 00)
Can you guess what this does?  That's right:
(6)[08] -= (2)[AD]
On the other hand, we can also subtract constants in the same manner:
MINUS2 (60, 08, 46, 00) becomes:
(6)[08] -= 0x46 (or 70 in base 10)

It's that simple.  (And that annoying.)  This is also likely the source of those switched byte things... just a change between source and destination.

Enjoy.

NOTE: There are more IDs than just 0, 1, 2, 5 and 6.  I know 3 and 4 exist... just haven't identified them yet.

lasyan3

  • *
  • Posts: 76
    • View Profile
Info about the field scripting language goes here.
« Reply #7 on: 2004-07-14 15:02:41 »
Oh God, but you are a master in assembling to find out such things so quickly! Ok, I will add those informations in my dumper right now!

Edit:
Here is the tool I used to make my dumper. It can contains interesting hints. the tool : http://lasyan3.free.fr/otherstools/ff7dasm.exe
An overview of the output : http://lasyan3.free.fr/otherstools/cargoin.asm
The sources : http://lasyan3.free.fr/otherstools/ff7_dasm.zip
« Last Edit: 2008-03-09 10:03:17 by lasyan3 »

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #8 on: 2004-07-14 23:53:11 »
Thanks, but most of it was just working through the dump and trying to figure out what FF7 was trying to do rather than poring over the disassembled dump of the executable.  Though that has helped in a few other topics...

Regarding the script dumper... I'd personally prefer it if, when you translate your current tool to work with the PC versions again, that it includes a copy of the raw data next to each line like the current version does.  Being able to go over the raw data can help at times.

I'd also appreciate it if, with variables, that you include the 'type' in brackets before it rather than renaming all of them as Global or Local... just helps ease identification on our side, is all, as well as with comparisons and ease of recognition.  Not a big issue though.

You probably already know this, but for Halkun's sake, I tracked down (3) and (4): they're the offset for the next block of 256 bytes after (1) and (2).  Need to track down (D) and (E) sometime, but it's not a pressing issue.

Finally, you can see why I'm anxious to get 'frcyo' to work with the script dumper.  I've already tackled two of the biggest script-based puzzles in the game, and Chocobo Breeding is one of the last to handle.  I'd also like 'games2' (the second part of Wonder Square) to work, but that's far less important; I just had idle curiousity about how some of the games (like the rock/paper/scissors game) worked.

Incidentally, the code for the Basketball game is really quite amusing.  I probably need to go peek at the Junon Formation minigame next for insights on keypresses and timing....

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #9 on: 2004-07-15 05:14:13 »
Man, I've been prepping for school and now I feel behind the power curve (;_;). I still haven't touched REQ (opcode 0x01) yet....

Explaning the memory and variable management is confusing the heck out of me. Now I fear I'm worse off that I started.

I think my problem is because It's a little whacked when compared to Sierra On-Lines AGI system, Enterbrain's RPGTskuru 5, or even Inforcom's Z-Machine system.

Sierra's scripting language has 255 one byte variables and 255 flags that could be set.

Enterbrains system had 999 vars and 999 flags.

Infocom had an object aria that allowed for 255 entities you could access.

All three systems did not directly access the computer's memory, but had it's own special "internal ram" that created a sandbox for the vars and flags to play in. That is not to say that there weren't system-dependant flags that you shouldn't write to. In all three systems these system flags and variables were kept rather low in memory and were useful for grabbing the current state of the virtual machine.

This scripting schema seems to be directly accessing memory, which I don't understand because the memory "accessors" (For lack of a better term) as waaay to small (max size is a long? That only give you 65536 bytes [64K] of address space) Maybe I can use a memory map or something to help sort this out. Is this just a syntaxual issue and I'm just not seeing it, or is it really that complex and close to the metal.

Laying out a memory map first is probably a good idea as then I can see the playground the scripting language can play in. Do you  really have full reign to all 2 meg of the system ram? That just seem really dangerous and non-portable to me.

Before I start mapping out opcodes I need to have a good understanding on how the memory system works, from what I'm reading it's not very elegent and I'm just haveing a bear of a time groking it.

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #10 on: 2004-07-15 05:45:25 »
No, it's restricted in what it can access; global variables are limited to certain portions (or entirety?) of the savemap (the area that FF7 saves out to disk/card when you save the game), and thus comprises of a few multiples of 256 bytes.  The temporary variables have their own space of 256 bytes, held seperately.  Any other memory addresses affected by the scripting systems are via the other opcodes and don't count as variables as the scripting engine knows them.

For instance, it can check who's in your battle party using the IF-PRTYQ( id, offset ) (if the party member identified by id is not in your party, skip the next 'offset' bytes starting your count and *including* the offset byte itself), but it's not using a standard scripting variable to do that.

The maximum amount of addresses the scripting language could concievably access (using its standard variable routines) is 7*256 or 1792 bytes, of which 256 of those are temporary, and I think lasyan has a further 256/512 bytes marked as illegal in his current PSX script dumper or something.

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #11 on: 2004-07-15 06:07:49 »
Why 7*256? Does each entity have it's own address space?

Also something just struck me...

If we break this scripting system, how much of it do you think is intact in games like FF8 and Parasite Eve?

Topher

  • *
  • Posts: 111
    • View Profile
Info about the field scripting language goes here.
« Reply #12 on: 2004-07-15 06:37:12 »
I'm willing to bet the opcodes are similar, but it wouldn't surprise me if they were dual-byte instead of single-byte.

Actually, I might take a look at some FF8 files in a short while.

Topher

  • *
  • Posts: 111
    • View Profile
Info about the field scripting language goes here.
« Reply #13 on: 2004-07-15 07:12:00 »
I found these in "ebexit6.fs" (Disc 1, field.fi):

Code: [Select]
squall
zell
selphie
quistis
rinoa
irvine
edea
dic

squall
squall::default
squall::talk
squall::push

zell
zell::default
zell::talk
zell::push
zell::bami
zell::oti

selphie
selphie::default
selphie::talk
selphie::push
selphie::bami
selphie::oti

quistis
quistis::default
quistis::talk
quistis::push
quistis::bami
quistis::oti

rinoa
rinoa::default
rinoa::talk
rinoa::push

irvine
irvine::default
irvine::talk
irvine::push
irvine::bami
irvine::oti

edea
edea::default
edea::talk
edea::push
edea::bami
edea::oti

dic
dic::defalut
dic::talk
dic::push


I don't know if it's just leftovers from development if it actually has something to do with the scripting engine, though. (And yes, dic::defalut is how it was spelled)

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #14 on: 2004-07-15 14:57:26 »
Why 7*256?

(1)[00] - (1)[FF] is 256 bytes.
(2)[00] - (2)[FF] is the *same* 256 bytes using words instead (let's assume for a second that (2)[FF] is illegal because it overlaps the next section... we won't, however, confirm this until we either look at the code or see that there's no script that uses it)

(3)[00] - (3)[FF] is a different set of 256 bytes.
(4)[00] - (4)[FF] is the *same* 256 bytes using words.

And so it goes on.  And then we also remember that (0)[??} means to use a constant rather than a variable.

So we have 1 number out of a possible 16 options reserved for constants, and the other 15 refer to memory spaces, with two each referring to the same memory space but giving the difference between bytes and words.  That means 7 possible ranges.  Of which 1 range is set aside for temporary variables, and we're not sure about the others except that 4 or 5 are definitely confirmed as global variables kept in the savemap.

lasyan3

  • *
  • Posts: 76
    • View Profile
Info about the field scripting language goes here.
« Reply #15 on: 2004-07-15 19:18:01 »
Quote from: Terence Fergusson
Regarding the script dumper... I'd personally prefer it if, when you translate your current tool to work with the PC versions again, that it includes a copy of the raw data next to each line like the current version does.  Being able to go over the raw data can help at times.

I'd also appreciate it if, with variables, that you include the 'type' in brackets before it rather than renaming all of them as Global or Local... just helps ease identification on our side, is all, as well as with comparisons and ease of recognition.  Not a big issue though.


What are you talking about ? Are you talking about my script dumper of the ff7dasm prog (which is not from me) ? And I'm not really sure to understand what you want me to change in the dumper. Please explain again, and as soon as I understand, I'll work on it, you can rely on me :wink:

trickstar66

  • *
  • Posts: 224
    • View Profile
    • http://radicalgarbage.250free.com
Info about the field scripting language goes here.
« Reply #16 on: 2004-07-15 19:34:04 »
Quote from: Lord Ramza
I don't know if it's just leftovers from development if it actually has something to do with the scripting engine, though. (And yes, dic::defalut is how it was spelled)

one question... what's dic?

MOD EDIT: Removed excessive quoted text.

Qhimm

  • Founder
  • *
  • Posts: 1996
    • View Profile
    • Qhimm.com
Info about the field scripting language goes here.
« Reply #17 on: 2004-07-15 20:02:14 »
Right, time to be harsh. And I'm already in a deliciously bad mood for it...

Quote from: trickstar66
one question... what's dic?

a) You quoted a huge, irrelevant text mass only to post a simple question, which definitely didn't require that text mass for context.
b) This thread's purpose is to collect and summarize information on the FF7 scripting language. Do you believe your post contributed to this?

This and the growing amount of small, irrelevant postings from you and a few others have become enough to get on my nerves (and apparently other members as well). You just received your second warning. Other members are wise to take notice as well, because I'll be handing out warnings more frequently from now on for anyone posting crap excessively. Please please please think before you post, "Will the forum members find this post useful?".

As for your question on the FF8 script "offshoot" (which really should get its own thread if there's interest to continue it), dic would most likely just be an object or NPC in the current field. There. Back on topic with you all.

EDIT: Oh yeah, just to make sure my own post isn't off-topic... I've located the code that executes all the different FF7 script opcodes in the FF7 PC executable. I'm still in the process of structuring the work, but I should be able to dig out information soon. If you need information on specific opcodes then let me know so I can focus on those.

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #18 on: 2004-07-15 20:15:22 »
Ah, thought it was your work since the download was on your site.  Didn't realise.  Looks like they already had variables figured out at the very least.  In that case, I'd rather prefer it if you worked on getting 'frcyo' working with your script dumper; we can mess around with opcodes and their real translations later.

lasyan3

  • *
  • Posts: 76
    • View Profile
Info about the field scripting language goes here.
« Reply #19 on: 2004-07-15 21:10:22 »
ok, it works now with the psx version of frcyo (decompressed), so it should be ok with the pc version. Check it out!
http://lasyan3.free.fr/mytools/script_dump.zip
« Last Edit: 2008-03-09 10:02:30 by lasyan3 »

Terence Fergusson

  • *
  • Posts: 262
    • View Profile
Info about the field scripting language goes here.
« Reply #20 on: 2004-07-15 21:43:35 »
It works.  Thanks.  I'll get to work on Chocobo Breeding then.

Edit: Well, locked down some more variables.  I'll just go over the types again fully...

(1/2) = 00DB1EC4
(3/4) = 00DB1FC4
(B/C) = 00DB20C4
(D/E) = 00DB21C4
(7/F) = 00DB22C4
(5/6) = 00CB2B80 (temporary variables)
(0) = Constants

This just leaves 8, 9 and A...

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #21 on: 2004-07-16 07:56:09 »
Didn't you just say above that bank 4/5 was the savemap? That looks to be spread between two different banks. Did I miss something?

Also does anyone have a quick copy of the FF7 save map, including how any checksums are calculated?

I'm torn where to put the memory map in gears. The save map belongs in the "Menu" section, the memory management belongs in "Kernel" and so far I've only seen "Field" make extensive use of the memory.

Should I split up the explanations?

Also I seem to have found out why I was gettng so confused about memory. Here I was thinking about the PSX memory map and not the PC one. Now that I can see the memory banks are contiguous, this is quite helpful.

The PSX has a high-speed scratchpad memory area internal to the CPU. It's 1k and between the ranges of 0x1f80_0000-0x1f80_03ff. You think there is a throwback in the PC code to represent this?

::EDIT::

Never mind, I see that the memory *ISN'T* contiguous. You have grouped the sections into blocks of memory.

::EDIT 2::
No wait, I'm confused. I'm letting my own assuptions get the best of me.

A PSX FF7 save has to fit into a single memory block of 8K. Now a PSX memory card has a finer "resolution" than that. The 8K block is actually split up into 64 "frames" made up of 128 bytes each. The first two frames are reserved for the filename and save icon. You can allocte the next two frames for additional icon animations, but isn't required. (Max allocations are 4 frames, one for the filename, and then three frames of animation)

Common sense is telling me that the savemap should be a direct mirror of what's saved on the card. This way a simple counter can attach the save data to the card stream. Writing to memory cards is a really qirkey process as it's really just another controller port. The more elegent solution, the faster the saves.

Qhimm

  • Founder
  • *
  • Posts: 1996
    • View Profile
    • Qhimm.com
Info about the field scripting language goes here.
« Reply #22 on: 2004-07-16 09:34:29 »
From what I know, the FF7 "save block" is a contiguous block of memory simply dumped to the memory card (with checksums and stuff added/updated of course). Common sense prevails again. :wink:  Now, the global script variables have five banks of 256 bytes each, all of which reside inside the memory area that constitutes the save block. Thus no specific bank refers to the savedata, rather they're all already in the save data. So another way to describe the banks would be temporary variables and permanent variables.

I hope that provided some information you were looking for.

halkun

  • Global moderator
  • *
  • Posts: 2097
  • NicoNico :)
    • View Profile
    • Q-Gears Homepage
Info about the field scripting language goes here.
« Reply #23 on: 2004-07-16 12:35:06 »
I'm mapping the save block with that little doc you had in the Jenova source there Qhimm. This will be in Gears and should work as a psudo-map for the field file's memory mapping.

Cyberman

  • *
  • Posts: 1572
    • View Profile
Info about the field scripting language goes here.
« Reply #24 on: 2004-07-16 15:44:47 »
Quote from: Lord Ramza
I found these in "ebexit6.fs" (Disc 1, field.fi):

Code: [Select]
SNIPED

I don't know if it's just leftovers from development if it actually has something to do with the scripting engine, though. (And yes, dic::defalut is how it was spelled)

It's likely dic::defalut is a mispelling by the programer.
If I were to hazard a guess these are function references, did you check if there were anything interesting around the text like addresses?

Cyb