PDA

View Full Version : Are there any global registers?



beefster09
11-08-2006, 06:48 PM
I just wondered, so I could enhance my frog-finding system.(Like skulltullas)
I heard something like this from the developers, but I don't know if it has been implemented or anything.

DarkDragon
11-09-2006, 07:51 AM
Yes.
Though this may change in the future, currently, to allocate a global register, just declare a variable in script scope:


ffc script foo {
int thisisglobal;
}

ffc script bar {
void run() {foo.thisisglobal = 2;}
}

ShadowTiger
11-09-2006, 12:07 PM
Hrm. I wish there was a way to differentiate variables between hardcoded non-variables in those vBulletin code tags. For example, "void" and "run" aren't variables, but I'd bet that "foo" and "thisisglobal" are. You'd imagine that such variable names would be absolutely common sense that they're user-created variables, but then again, with me seeing so many variables called "this->" (That exact variable, "this" .. yes.) it's getting hard to tell. I'm no C++ programmer, and they can get rather technical sometimes.


... Wow, that's rather off topic. Sorry. XD Just thinking out loud.


So, any FF script can refer to a global variable if it's already been created by another somewhere else. What determines if a variable will be global or not though? How would you set one up to be global vs a single-script variable?

Saffith
11-09-2006, 02:53 PM
I wish there was a way to differentiate variables between hardcoded non-variables in those vBulletin code tags. For example, "void" and "run" aren't variables, but I'd bet that "foo" and "thisisglobal" are.Technically, foo is the name of the script, which is different from a variable. It is user-defined, though, if that's what you mean.


You'd imagine that such variable names would be absolutely common sense that they're user-created variables, but then again, with me seeing so many variables called "this->" (That exact variable, "this" .. yes.) it's getting hard to tell.this isn't a variable; it's a pointer to the current FFC. Whenever you see this->anything, it's accessing the properties of the FFC that's running the script.


What determines if a variable will be global or not though? How would you set one up to be global vs a single-script variable?If I'm not mistaken, the way it is now, any variables declared inside run() or outside of any function are automatically global.

ShadowTiger
11-09-2006, 08:31 PM
It is user-defined, though, if that's what you mean.Ah, yes, it is. :) Thank you Saffith, as always. ^^.



this isn't a variable; it's a pointer to the current FFC. Whenever you see this->anything, it's accessing the properties of the FFC that's running the script.... Aah, so it's hardcoded. So I can never use it to refer to anything but the FFC that's running the script. Stupid question, but can we make it refer to the script too? (I told you this was a stupid question. :blah: )


If I'm not mistaken, the way it is now, any variables declared inside run() or outside of any function are automatically global.... Hm. L_L' Why run() of all things though. ... I think this is one of those things where I'd have to study ZScript as a whole to understand this concept rather than asking one question at a time related to it. (Sort of like trying to put a puzzle together by randomly placing pieces on the board, hoping it'll form some semblance of a picture, rather than starting from the base piece and working off of that one. Naturally, the latter is better.)

beefster09
11-09-2006, 08:49 PM
So... Zscript is object oriented. Will you, in fact, be able to change a user-defined variable at any time? Where is it stored?

Saffith
11-10-2006, 01:55 AM
So I can never use it to refer to anything but the FFC that's running the script. Stupid question, but can we make it refer to the script too?I'm not entirely sure what you mean. Do you mean, say, to change which script the FFC is running? Or to change the text of the script itself in some way?


Will you, in fact, be able to change a user-defined variable at any time?Yeah, pretty much.


Where is it stored?Global variables are stored in the global registers (gd0-gd255).


... Why is it that quotes are only italicized if the quotee's name is given? That's bizarre.

DarkDragon
11-10-2006, 07:45 AM
Variables declared inside run() should NOT be global; if they currently are it's a bug ;)

C-Dawg
11-10-2006, 11:31 AM
They may not be global, but other FFCs on the screen using variables of the same name certainly like to change them.

Saffith
11-10-2006, 01:58 PM
Actually, it seems it's not quite as simple as I thought.


ffc script foo
{
void run()
{
int temp;
temp=this->X;
Waitframe();
this->X=temp;
}
}
If you assign that to two FFCs on the same screen, it should set their X positions to the same value if temp is global. It doesn't do that.
I'm pretty sure they're not entirely contained—that was the problem with multiple chaser traps, for example—but they're not simply global, either.

beefster09
11-11-2006, 12:45 AM
So there really are gd0-gd255?

Saffith
11-11-2006, 04:56 AM
Yeah. You can access them using precisely those names in ZASM. In ZScript, you can't access them directly; you just create a global variable, and the compiler will find a place for it. Since you don't know what it'll pick, it can be dangerous to mix ZASM and ZScript in a single quest.

beefster09
11-11-2006, 05:15 PM
So how do you declare a global variable? Will it save when you save your game? Can you access local variables directly using ZScript?

Saffith
11-11-2006, 11:30 PM
So how do you declare a global variable?
Anything declared within the script body, outside of any method, is automatically global. It can be referred to from another script using scriptName.variableName.
This may change, though.


Will it save when you save your game?
... I think so, yeah. I'll have to check and make sure, but I think they're saved.


Can you access local variables directly using ZScript?I'm not sure I know what you mean... That's pretty much the only way you would access them.

DarkDragon
11-13-2006, 11:35 AM
I'm very interested in this bug. When Saffith's sample script is compiled, temp will be stored on foo's stack. Since each script SHOULD have a separate stack, that two script's local variables are interfering with each other indicates something has gone horribly wrong at runtime.
Could somebody take two scripts which are known to interfere with each other, and pare them down to a minimal set of scripts that still exhibit the bug? As soon as we get two SMALL scripts that illustrate the bug, we need to look at the ASM dumps and determine if the bug is both a compile-time and runtime bug or just runtime.

Saffith
11-13-2006, 04:35 PM
This is about as small as I can manage.
I'm fairly certain it has something to do with this. If I avoid it, there's never a problem.


ffc script foo
{
void run()
{
int var=this->X;
Trace(var);
}
}

ffc script bar
{
void run()
{
int var=this->X;
Trace(var);
}
}

I compile those, attach foo to FFC #1 and bar to FFC #2, and it prints the position of #1 twice.


foo
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3

bar
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3

Also, if I only use one of those and attach it to both FFCs, I get the same output.


ffc script foo
{
void run()
{
int var=this->X;
Trace(var);
}
}
Same ol' ASM.

foo
SETV d2,0
SETR d3,REFFFC
PUSHR d3
PUSHR d2
SETR d4,SP
PUSHR d4
SETV d2,14
PUSHR d2
SETR d6,d4
ADDV d6,0
LOADI d2,d6
PUSHR d2
GOTO 34
POP d4
SETR d6,d4
ADDV d6,1
STOREI d2,d6
PUSHR d4
SETV d2,26
PUSHR d2
SETR d6,d4
ADDV d6,1
LOADI d2,d6
PUSHR d2
GOTO 30
POP d4
SETV d3,0
POP d3
QUIT
POP d3
TRACER d3
POP d3
GOTOR d3
POP d3
SETR REFFFC,d3
SETR d2,X
POP d3
GOTOR d3

C-Dawg
11-13-2006, 05:59 PM
Saffith, do you want to forward that quest file I emailed you on to DarkDragon? If he wanders around that quest for awhile (normal cheats enabled) he'll find some examples of the bizzare FFC behavior first hand.

DarkDragon
11-14-2006, 11:41 AM
1 SETV d2,0 ; placeholder
2 SETR d3,REFFFC ; value of the this pointer
3 PUSHR d3
4 PUSHR d2
5 SETR d4,SP
6 PUSHR d4 ; stack is now: 0, this, 254
7 SETV d2,14 ; return value
8 PUSHR d2
9 SETR d6,d4
10 ADDV d6,0
11 LOADI d2,d6 ; d2 is now this
12 PUSHR d2 ; stack is now 0, this, 254, 14, this
13 GOTO 34
14 POP d4 ; SP is popped off of the stack. Stack is now 0, this. d2 holds X.
15 SETR d6,d4
16 ADDV d6,1
17 STOREI d2,d6 ; Stack is now X, this.
18 PUSHR d4 ; Stack is now X, this, 254
19 SETV d2,26 ; return value
20 PUSHR d2 ; stack is now X, this, 254, 26
21 SETR d6,d4
22 ADDV d6,1
23 LOADI d2,d6 ; d2 now holds X
24 PUSHR d2 ; stack is now X, this, 254, 26, X
25 GOTO 30
26 POP d4 ; pops SP off of the stack. Stack is now X, this
27 SETV d3,0 ; NOP
28 POP d3
29 QUIT

30 POP d3 ; pops X off of the stack
31 TRACER d3
32 POP d3 ; pops return value 26 off of the stack
33 GOTOR d3

34 POP d3 ; this is popped off of the stack
35 SETR REFFFC,d3
36 SETR d2,X ; d2 is now X
37 POP d3 ; 14 is popped off of the stack
38 GOTOR d3
I've added line numbers, some commentary, and split the subroutines off of your ASM dump; if there's a bug in the ASM I don't see it.

What happens if you run two FFCs on the same screen with the following ZASM script:


LOADR d3, REFFFC
TRACER d3
QUIT

Saffith
11-14-2006, 02:41 PM
You meant SETR, not LOADR, right?

I attached it to eight different FFCs. For the first two, the output isn't entirely predictable. One of them prints #1's X position, and the other one prints 0. It seems as if the order of those two somehow depends on their positions.
For FFCs #3-8, however, it simply prints the numbers 2-7 in order.

beefster09
11-14-2006, 11:35 PM
Yes, but how do you declare a global variable that can be acessed anywhere in the game?

C-Dawg
11-15-2006, 10:00 AM
And we only get a limited number of global variables, right? So if I want to make a set of global variables that mirror Link's inventory, checking for all items he could possibly have, do I even have enough space to do that? I guess I could use some creative data structure, where I use X bits to determine unique combinations of 2^X different items, but I'll be damned if that doesn't sound like a pain in the ass.

DarkDragon
11-15-2006, 11:11 AM
You meant SETR, not LOADR, right?
Oops, yes, yes I did.


I attached it to eight different FFCs. For the first two, the output isn't entirely predictable. One of them prints #1's X position, and the other one prints 0.
:odd:
Well, here's the bug. REFFFC should be intialized to 0 for the first FFC, 1 for the second, etc. If they are being set to unpredictable values, then yes, cross-script intereference is very possible.


So if I want to make a set of global variables that mirror Link's inventory, checking for all items he could possibly have, do I even have enough space to do that?
Well, there are 256 item slots, of which a little over 100 are used now, so yes, you could use global variables. But since each global is a long, it would be much more efficient to use individual bits. When arrays are implemented that won't be too bad to implement; right now it's so painful that it's probably not worth doing.

EDIT: Sorry beefster09, I completely missed your post.
Gobal variables are always totally global, you don't need to do anything special to access them from elsewhere in the game.

beefster09
11-15-2006, 11:16 AM
Thank you!