Jump to content

Photo

Oh hey, oddity about calling global arrays within global arrays.

2.5.2 Oddity ZC Dark Arts

  • Please log in to reply
3 replies to this topic

#1 Orithan

Orithan

    Studying Scientist - Commission from Silvixen

  • Members
  • Location:Australia

Posted 28 May 2017 - 06:52 AM

On my misadventures through ZScript today, I ran into a rather odd occurance that could be explained by delving deep into territory that perhaps people should keep out of, which will get depreciated in ZC 3.0.

 

When calling global arrays within global arrays, both the array that is calling the array and any arrays that are to be called within said array must be declared in the same file. If they are declared in separate files, they will be imported and declared but attempting to call them within the global array that is to call it results in a compile error; specifically "Variable [name] is undeclared"

 

Let me show you the example I just did

//Requires std.zh, string.zh and tango.zh to be imported here

//Tango styles used by the quest.

//Text settings
const int ITEMMESSAGE_TEXT_CSET = 0;
const int ITEMMESSAGE_TEXT_COLOUR = 1;

//Backdrop settings
const int ITEMMESSAGE_BACKDROP_TILE = 30080;
const int ITEMMESSAGE_BACKDROP_CSET = 5;
const int ITEMMESSAGE_BACKDROP_WIDTH = 14; //In tiles
const int ITEMMESSAGE_BACKDROP_HEIGHT = 4; //In tiles

// "More..." icon combo and CSet
const int ITEMMESSAGE_MORE_COMBO = 15536;
const int ITEMMESSAGE_MORE_CSET = 5;

// Cursor combo and CSet
const int TQS_CURSOR_COMBO = 410;
const int TQS_CURSOR_CSET = 0;

// Menu sound effects
const int TQS_SFX_MOVE = 5;
const int TQS_SFX_SELECT = 21;
const int TQS_SFX_CANCEL = 0;

const int STYLE_MESSAGE = 0;


//Both the following arrays must be declared in the same file. If you declare them in separate files, the compiler will spit out a "Variable [name] is undeclared" error

//Standard message backdrop, run for item and FFC scripts that use arguments for text
int StdMessageBackdrop[]= {
    TANGO_DRAW_TILE, //Top left corner
        ITEMMESSAGE_BACKDROP_TILE,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        0, 0,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Top right corner
        ITEMMESSAGE_BACKDROP_TILE+13,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        208, 0,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //bottom left corner
        ITEMMESSAGE_BACKDROP_TILE+60,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        0, 48,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //bottom right corner
        ITEMMESSAGE_BACKDROP_TILE+73,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        208, 48,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Top border. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+1,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        16, 0,  // X, Y (pixels)
        12, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Middle. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+21,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        16, 16,  // X, Y (pixels)
        12, 2, // Width, height (tiles)
    TANGO_DRAW_TILE, //bottom border. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+61,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        16, 48,  // X, Y (pixels)
        12, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Left border. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+20,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        0, 16,  // X, Y (pixels)
        1, 2, // Width, height (tiles)
    TANGO_DRAW_TILE, //Right border. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+33,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        208, 16,  // X, Y (pixels)
        1, 2, // Width, height (tiles)
    TANGO_DRAW_TILE, //Left edge of optional namebox. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+14,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        0, 64,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Middle of namebox. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+15,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        16, 64,  // X, Y (pixels)
        3, 1, // Width, height (tiles)
    TANGO_DRAW_TILE, //Right edge of namebox. Can be adjusted
        ITEMMESSAGE_BACKDROP_TILE+18,   // Tile
        ITEMMESSAGE_BACKDROP_CSET,     // CSet
        64, 64,  // X, Y (pixels)
        1, 1, // Width, height (tiles)
    TANGO_DRAW_TEXT, //Current name. Can be adjusted
        MsgCurrentName,   // String Pointer
		TANGO_FONT_LTTP_SMALL, //Font
        ITEMMESSAGE_TEXT_CSET,     // CSet
		ITEMMESSAGE_TEXT_COLOUR,	// Colour
        4, 69,  // X, Y (pixels)
    TANGO_DRAW_END
};


int TANGO_FONT_LTTP_SMALL[] = {
    TANGO_FONT_BUILTIN,
    TANGO_FONT_PROPORTIONAL,
    FONT_Z3SMALL,
    0, // Unused
    6, // Character height
    0, // Space between lines
    
    // Character widths, including any trailing space
    // ASCII characters 32 to 126
    
    // sp !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /
       4, 2, 4, 6, 6, 4, 5, 2, 3, 3, 4, 4, 3, 4, 2, 4,
    
    // 0  1  2  3  4  5  6  7  8  9
       4, 3, 4, 4, 4, 4, 4, 4, 4, 4,
    
    // :  ;  <  =  >  ?  @
       2, 2, 4, 4, 4, 4, 6,
    
    // A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z
       5, 5, 4, 5, 4, 4, 5, 4, 2, 4, 5, 4, 6, 5, 5, 5, 6, 5, 4, 4, 5, 6, 6, 4, 4, 4,
    
    // [  \  ]  ^  _  `
       4, 4, 4, 4, 4, 4,
    
    // Note: This font's capital and lowercase letters are identical, but
    // ZC spaces some of them differently. This appears to be unintentional,
    // so it is not duplicated here.
    // a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
       5, 5, 4, 5, 4, 4, 5, 4, 2, 4, 5, 4, 6, 5, 5, 5, 6, 5, 4, 4, 5, 6, 6, 4, 4, 4,
    
    // {  |  }  ~
       4, 2, 4, 5,
    
    // Additional characters
       6, 10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
       4, 4, 4, 4, 4, 4, 4, 4, 4
};

int MsgCurrentName[30] = "Hal Hunter"; //Buffer used for the name.


#2 Saffith

Saffith

    IPv7 user

  • ZC Developers

Posted 28 May 2017 - 12:37 PM

Definitely something weird going on there, but I'm not exactly sure what.

This works:
int x;
int y[]={x};
And this works:
int x[]={y};
int y;
This one tells me x is undeclared:
int x[1];
int y={x};
But this works:
int x[]={y};
int y[1];
So global variables are only visible before their declarations if they're declared as arrays, I guess? I'm not quite sure what the deal is.

I can see why it would be tricky. Global arrays are initialized at runtime by the Init script, and allowing, for instance, two arrays to be initialized with pointers to each other would require some special handling. I suspect this is related to that, but it's an odd way for the limitation to manifest.

#3 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 28 May 2017 - 03:03 PM

Definitely something weird going on there, but I'm not exactly sure what.

So global variables are only visible before their declarations if they're declared as arrays,

I guess? I'm not quite sure what the deal is.

I can see why it would be tricky. Global arrays are initialized at runtime by the Init script, and allowing, for instance, two arrays to be initialized with pointers to each other would require some special handling. I suspect this is related to that, but it's an odd way for the limitation to manifest.

 

(spoiler tags mine, added to increase readability of a lengthy post).

I believe that this is a natural result of global array pointers being associated in an order in the reverse of their declaration. Simple global vars are handled prior to arrays, and are thus always available...

 

Thus,

 

//This compiles

int x[]={y[0]}; //x[0] can be initialised because the pointer for y[] is known.

int y[1]; //The pointer for y[] is determined first, and is available to x[]

 

//This does not

int y[1];

int x[]={y[0]}; //The pointer for y[] is not yet known, as x[] is evaluated *first* and x[0] cannot be initialised.

 

//Either of these wck:

int x; //the simple var 'x' is handled prior to arrays needing to initialise.

int y[]={x}; //The simple var x is available to be initialised to y[0].

 

//or...

int y[]={x}; //The simple var x is available to be initialised to y[0].

int x; //the simple var 'x' is handled prior to arrays needing to initialise.

 

Have a look at the actual IDs for global array pointers, and you will see this happening.

 

An appropriate fix would be to sort out all the array pointer IDs before initialising any of their values, with an additional scanning phase. In fact, it may already be fixed as @grayswandir added a lot of new code for global arrays.

 

 

FWIW, code like this is now legal:

 

const int INDEX_SIZE_BASE = 5;

const int INDEX_SIZE_MOD = 10;

int arr[INDEX_SIZE_BASE*INDEX_SIZE_MOD];


Edited by ZoriaRPG, 28 May 2017 - 03:21 PM.


#4 grayswandir

grayswandir

    semi-genius

  • ZC Developers

Posted 28 May 2017 - 10:06 PM

I think this is already fixed in the git version. (The reversed ordering, I mean.)

 

I thought this was already covered in my test script, but apparently not, so I'll go ahead and add it. So in any case in shouldn't be in the final release.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users