Perhaps it is called a virtual array, we just call it a const table. Here's an example from C from a project I'm working on now:
Then, whenever I need to use any element of that table, I use it just like an array, such as:
I can assure you, the data in this table is not stored in RAM (I only have 128k of RAM to play with, I'd very quickly run out if we had to store the const tables in RAM). It is stored as part of the binary executable file just like the data in DATA statements in BASIC. We use this ALL the time to store quick data we need. The table can even be made of data from a struct (kind of like a Type), such as this one:
Which can then be accessed by things like:
You can even make a multi-dimensional const table with each element containing a type (after a while the formatting gets harder to read when you add too much complexity, but it is doable).
I don't know how you guys can live without having access to large organized tables of data that don't take up RAM or require reading from a data file. How do all the larger game projects in Blitz deal with the raw data needed for code? Do you have to use individual constants for each variation on a single type, like ENEMY_HIT_POINTS_DROID and ENEMY_HIT_POINTS_PIRATE and ENEMY_HIT_POINTS_ZOMBIE and so on instead of just enemyHitPoints[enemyType]?
static const u16 EnemyJumpType[ENEMY_MAX_JUMP_CHARS_X][ENEMY_MAX_JUMP_CHARS_Y] = {//X = 0 1 2 3 4 5 6 { EJ_HIGH, EJ_NORM, EJ_NORM, EJ_NONE, EJ_NONE, EJ_NONE, EJ_NONE }, // Y = 0 { EJ_HIGH, EJ_NORM, EJ_NORM, EJ_NORM, EJ_NONE, EJ_NONE, EJ_NONE }, // Y = 1 { EJ_SHRT, EJ_MIDL, EJ_NORM, EJ_NORM, EJ_NONE, EJ_NONE, EJ_NONE }, // Y = 2 { EJ_SHRT, EJ_SHRT, EJ_MIDL, EJ_NORM, EJ_NORM, EJ_LONG, EJ_NONE }, // Y = 3 { EJ_SHRT, EJ_SHRT, EJ_MIDL, EJ_MIDL, EJ_NORM, EJ_LONG, EJ_LONG }, // Y = 4 };
Then, whenever I need to use any element of that table, I use it just like an array, such as:
if (EnemyJumpType[x][y] == EJ_NORM) enemyJump(NORMAL_JUMP_HEIGHT);
I can assure you, the data in this table is not stored in RAM (I only have 128k of RAM to play with, I'd very quickly run out if we had to store the const tables in RAM). It is stored as part of the binary executable file just like the data in DATA statements in BASIC. We use this ALL the time to store quick data we need. The table can even be made of data from a struct (kind of like a Type), such as this one:
typedef struct _STAGE_DATA_TYPE { u16 *BG0MapFile; u16 *BG1MapFile; s16 HeroXPos; s16 HeroYPos; } STAGE_DATA_TYPE; static const STAGE_DATA_TYPE StageData[NUM_STAGES] = {// BG0MapFile BG1MapFile HeroXPos HeroYPos { (u16*)&RES_MAP1_BG0_BMP_SA, (u16*)&RES_MAP1_BG1_BMP_SA, 8, 33, }, // Map 0 { (u16*)&RES_MAP2_BG0_BMP_SA, (u16*)&RES_MAP2_BG1_BMP_SA, 44, 33, }, // Map 1 { (u16*)&RES_MAP3_BG0_BMP_SA, (u16*)&RES_MAP3_BG1_BMP_SA, 35, 33, }, // Map 2 };
Which can then be accessed by things like:
InitHero( StageData[curStage].HeroXPos, StageData[curStage].HeroYPos );
You can even make a multi-dimensional const table with each element containing a type (after a while the formatting gets harder to read when you add too much complexity, but it is doable).
I don't know how you guys can live without having access to large organized tables of data that don't take up RAM or require reading from a data file. How do all the larger game projects in Blitz deal with the raw data needed for code? Do you have to use individual constants for each variation on a single type, like ENEMY_HIT_POINTS_DROID and ENEMY_HIT_POINTS_PIRATE and ENEMY_HIT_POINTS_ZOMBIE and so on instead of just enemyHitPoints[enemyType]?