[Fixed] Global variables in libraries

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Global variables in libraries

Post by Ty Halderman »

I seem to be able to declare global (world) variable arrays okay if I put them in a common #include file and reference them from code in each of 2 maps' scripts, but if I call common library routines to manipulate them, it seems that the values get lost between maps. Is it possible that variables used in libraries aren't being initialized right? In particular, that they are perhaps initializing when they shouldn't?

This happens whether the library declares the variables or includes a common file to do so--it keeps track fine while in a single map, but when the map changes, the values are all zeroed. Map change is "normal" (not a IDCLEV cheat) and is within the same hub, even.

Picture this, basically:

Code: Select all

world int 42:fred[];  // in the #included file for maps and library

MAP01:

// supposed to store 37 to subscript 2 of fred[]
f_putval(2,37); 
x = getval(2);  // returns 37

MAP02:

// supposed to retrieve said value from fred[2] 
x = f_getval(2); // returns zero

LIBUTIL:

function void f_putval(int ix, int amount)
{
   fred[ix] = amount;
}

function int f_getval(int ix)
{
   return fred[ix];
}
I wrote that from scratch in this post--forgive any minor syntax errors.
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Post by Ty Halderman »

Boo! :shock:

I know it's hard to hear me over the more vociferous and "occasionally" off-topic forum posteurs, but... Does anyone have a thought on this?

I wonder if messages bump to the top here... BUMP
User avatar
randi
Site Admin
Posts: 7728
Joined: Wed Jul 09, 2003 10:30 pm

Post by randi »

The attached wad works fine for me.

The source for funcs.acs:

Code: Select all

#library "funcs"

global int 1:foofoo[];

function void set_val (int e, int v)
{
	foofoo[e] = v;
}

function int get_val (int e)
{
	return foofoo[e];
}
The source for map01.acs:

Code: Select all

#import "funcs.acs"


script 1 open
{
	set_val (56, 111);
	print (s:"On map 1, val 56 = ", d:get_val (56));
	delay (35);
	exit_normal (0);
}
The source for map02.acs:

Code: Select all

#import "funcs.acs"

script 1 open
{
	print (s:"On map 2, val 56 = ", d:get_val (56));
}
You do not have the required permissions to view the files attached to this post.
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Post by Ty Halderman »

Okay, it wasn't libraries, it was nested function calls that were the issue, though I happen to use them in libraries and was suspicious of the more complex possibility first :oops:

Anyway, here's some code that shows the problem. One-room wad attached, just PUKE 1 to trigger it.

Code: Select all

script 1 (void)  // trigger with PUKE 1
{
   f1();
}

function void f1(void)
{
   int y = 2;

   print(s:">F2 y=",d:y); // >F2 y=2
   f2();
   print(s:"<F2 y=",d:y); // <F2 y=1
}

function void f2(void)
{
}

Results of the print statements are in the comments on those lines. As you can see, the value of y changes by calling f2(). I've had variables and other stuff in f2 but kept trimming it down to the simplest case.
You do not have the required permissions to view the files attached to this post.
User avatar
randi
Site Admin
Posts: 7728
Joined: Wed Jul 09, 2003 10:30 pm

Post by randi »

Okay, thanks. When the second function returned, the pointer to the first function's local variables was being set to point inside of its return info instead of at its variables. If you've still got the source, change line 2526 of p_acs.cpp from this:

Code: Select all

locals = &Stack[sp - activeFunction->ArgCount - activeFunction->LocalCount];
To this:

Code: Select all

locals = &Stack[sp - activeFunction->ArgCount - activeFunction->LocalCount - sizeof(CallReturn)/sizeof(int)];
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Post by Ty Halderman »

Great, thanks Randy. I do have the source for .47 so I'll add that.
Mighty Duck X-treme
Posts: 272
Joined: Tue Jul 15, 2003 5:48 pm
Location: Chesterfield, Missouri

Post by Mighty Duck X-treme »

Speaking of the .47 source, when will that be out? 8-)
boris
Posts: 702
Joined: Tue Jul 15, 2003 3:37 pm

Post by boris »

Mighty Duck X-treme wrote:Speaking of the .47 source, when will that be out? 8-)
Get the source for .43 and diff it to .47
User avatar
Hirogen2
Posts: 2030
Joined: Sat Jul 19, 2003 6:15 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: Central Germany

Post by Hirogen2 »

Can there be scripts in libraries?
And in general, where are libs stored? Imported into any map01.acs, or have they a single behavior lump?
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Post by Ty Halderman »

In the wad, the libraries are in an A_START / A_END block. You put the .o files from compiling the libraries in that as lumps with the name assigned in the library code.

Example:

Library file is UTIL.ACS
Put this line at the top of it:
#library "UTIL"
Compile it with ACC
Insert UTIL.O as lump UTIL in the A_START/A_END block in your wad

The actual filename of the .ACS and thence .O file don't actually have to be UTIL in this example, but the lump and the name in the #library line have to match. I happen to call mine LIBUtil.ACS in this case to differentiate the library files from the map files.
You can put anything you like in a library, and it'll be accessible to all levels' scripts.

I never did get .47 to compile so I did a workaround and will double-check my code against the changes Randy gave above once .48 or whatever is available.
User avatar
Hirogen2
Posts: 2030
Joined: Sat Jul 19, 2003 6:15 am
Graphics Processor: Intel with Vulkan/Metal Support
Location: Central Germany

Post by Hirogen2 »

What can be contained in i.e. LIBUTIL lump? Only scripts, functions, or both? Even world/map vars?
User avatar
Ty Halderman
... in loving memory ...
Posts: 282
Joined: Thu Jul 17, 2003 9:53 pm
Location: New Orleans LA

Post by Ty Halderman »

Scripts, functions and world vars. Map vars wouldn't make sense--this isn't technically "in" a map, just referenced by it. I use it primarily to put common functions in such as message output, generic functions, things I'd have to kill you if I told you...

Sphagne has an entry in the Scrapbook that's a better explanation than mine here, and there's a link to LWM's demo of one too.

Return to “Closed Bugs”