Day 35: assert(TileX < TileMap->ChunkDim) triggering in GetTileValueUnchecked

Hi

I am trying to follow along with Casey's code but I keep triggering this assert statement when walking in the world and Casey's does not. Here are a few code snippets to describe the problem:
(Note, I did change some of the variable names to match my preferences but the rest should be the same)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
gameState->gameWorld = pushSize(&gameState->worldArena, world);
world *gameWorld = gameState->gameWorld;
gameWorld->tileMap = pushSize(&gameState->worldArena, tile_map);

tile_map *tileMap = gameWorld->tileMap;


tileMap->chunkShift = 4;
tileMap->chunkMask = (1 << tileMap->chunkShift) - 1;
tileMap->chunkDim = (1 << tileMap->chunkShift);

tileMap->tileChunkCountX = 128;
tileMap->tileChunkCountY = 128;
    
tileMap->tileChunks = pushArray(&gameState->worldArena,
			    tileMap->tileChunkCountX * tileMap->tileChunkCountY,
			    tile_chunk);

tileMap->tileSideInMeters = 1.4f;


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  real32 screenCenterX = 0.5f * (real32) buffer->width;
  real32 screenCenterY = 0.5f * (real32) buffer->height;

  for (int32 i = -10; i < 10; ++i) {
    for (int32 j = -20; j < 20; ++j) {
      uint32 column = gameState->playerP.absTileX + j; // <-- this is where the addition = ChunkDim
      uint32 row = gameState->playerP.absTileY + i;
      
      uint32 tileID = getTileValue(tileMap, column, row); // <-- this is where the assert throws, see below

      if (tileID > 0) {
	
	real32 grey = 0.5f;
      
	if (tileID == 2)
	  grey = 1.0f;

	if (row == gameState->playerP.absTileY && column == gameState->playerP.absTileX)
	  grey = 0.0f;

	real32 centerX = screenCenterX -
	  (metersToPixels * gameState->playerP.tileRelX) +
	  ((real32) j) * tileSideInPixels;
	real32 centerY = screenCenterY +
	  (metersToPixels * gameState->playerP.tileRelY) -
	  ((real32) i) * tileSideInPixels;

	real32 minX = centerX - (0.5f * tileSideInPixels);
	real32 minY = centerY - (0.5f * tileSideInPixels);
	real32 maxX = centerX + (0.5f * tileSideInPixels);
	real32 maxY = centerY + (0.5f * tileSideInPixels);
      
	drawRectangle(buffer, minX, minY, maxX, maxY, grey, grey, grey);
      }
    }
  }


1
2
3
4
5
6
internal uint32 getTileValue(tile_map *tileMap, uint32 absTileX, uint32 absTileY) {
  tile_chunk_position chunkPos = getChunkPosFor(tileMap, absTileX, absTileY);
  tile_chunk *tileChunk = getTileChunk(tileMap, chunkPos.tileChunkX, chunkPos.tileChunkY);

  return getTileValue(tileMap, tileChunk, absTileX, absTileY);
}


1
2
3
4
5
6
7
8
9
inline uint32 getTileValue(tile_map *tileMap, tile_chunk *tileChunk, uint32 testTileX, uint32 testTileY) {
  uint32 result = 0;

  if (tileChunk && tileChunk->tiles) {
    result = getTileValueUnchecked(tileMap, tileChunk, testTileX, testTileY);
  }
  
  return result;
}


1
2
3
4
5
6
7
inline uint32 getTileValueUnchecked(tile_map *tileMap, tile_chunk *tileChunk, uint32 tileX, uint32 tileY) {
  assert(tileChunk);
  assert(tileX < tileMap->chunkDim); // <-- assertion failed: tileX == tileMap->chunkDim
  assert(tileY < tileMap->chunkDim);
  
  return tileChunk->tiles[(tileY * tileMap->chunkDim) + tileX];
}


I would really appreciate it if someone could help me--I've been banging my head against this problem for a month now.

(Je parle francais aussi, si qqu est plus comfortable avec ca)

Edited by Gab on
You're using absTileX and absTileY where you need to use chunkPos.relTileX and chunkPos.relTileY on the return line.

1
2
3
4
5
6
7
internal uint32 getTileValue(tile_map *tileMap, uint32 absTileX, uint32 absTileY) {
  tile_chunk_position chunkPos = getChunkPosFor(tileMap, absTileX, absTileY);
  tile_chunk *tileChunk = getTileChunk(tileMap, chunkPos.tileChunkX, chunkPos.tileChunkY);

  // return getTileValue(tileMap, tileChunk, absTileX, absTileY);
  return getTileValue(tileMap, tileChunk, chunkPos.relTileX, chunkPos.relTileY);
}


To debug that kind of issues, you should use a debugger.
- When the assert trigger, use the call stack to see the value of "i" and "j" in the caller functions (and it would probably be helpful to call "i" and "j" => "y" and "x").
- Either place a conditional breakpoint or some code at the start of the i and j loop to break on it when the value correspond to the value giving the error.
1
2
3
4
5
6
7
8
9
for (int32 i = -10; i < 10; ++i) {
    for (int32 j = -20; j < 20; ++j) {
        
        if ( i == 3 && j == 7 ){ /* The value of i and j when the assert triggers. */
            __debugbreak(); /* This cause the debugger to stop. */
        }
        /* The rest of the code. */
    }
}

- Step in the code and don't assume anything. Check each variable value to see if it's value is what you expect.

Edited by Simon Anciaux on Reason: Code error
*facepalm*

Thank you so much. When going through the debugger, had assumed the problem was else where. Totally didn't notice that I was getting the chunkPos and never really using it.

Thanks again.