That is exactly the problem yeah!
So that line is trying to find where in the map the X coordinates land based on the tile’s width. In this case 16. The problem indeed is that anywhere between -1 and 0 should be skipped but it is always read as 0 due to precision loss in integers.
I’ve tried using camera as a float but then I have all this struggle getting the values aligned/converted/moved through the rest of the process
I am thoroughly convinced there is a better way to do the entire thing. But I’m yet inexperienced in the maths necessary to figure it out.
As mentioned too I’ve tried to dissect and do most the same as from the current c++tasmode but I clearly don’t have a solid understanding of what’s happening there
I’ll try to explain what is happening better here:
void fillLine(ushort[] line, int y) {
// Clip top and bottom of map.
if(y-cameraY < 0 || y-cameraY >= mapHeight*tileH)return;
Here I am checking if the offset of the cameraY position causes the position to be over (<0) or under (greater than the height of the map, which is in tiles so we multiply by the height of the tiles for the true height in pixels). Pretty straight forward, but ugly…
// Set the Y for the map and tileset lookup
var mapY = ((y-cameraY) / 16) * mapWidth;
var tileY = ((y-cameraY) % 16) * tileW;
Here I am collecting the Y position in the Map array (which is an array of tile ID’s) and then also collecting the Y position within the tile itself (in this case 16 is the height of the tile). Nothing too interesting here, but again, the math looks ugly and there may be better ways to determine where on the map/tile the current passed in line should fall.
// Divide the current X position by the width of the Tiles.
var mapX = cameraX / tileW;
// Get the position on the first X Tile.
var tileX = cameraX % tileW;
Similar, I thought, to how I get the Y position, here I attempt to get where the X positions for map and tile. Firstly by dividing the camera’s position to the width of a tile and then the X position of where to start in the tile itself.
// Loop the map width to collect the tiles
for (int i = 0; i < 220;) {
// Clip the right hand side of the map. Whee~
if(mapX >= mapWidth)return;
We loop over the width of the screen, since we are populating a line . Starting we try to see if the mapX is outside of the map’s width. Don’t need to put anything there if we aren’t on the map.
int iter = Math.min(tileW - tileX, 220 - i);
Getting the length of the tile to render. This helps find on the left/right side of the map in the case where only a partial tile should be rendered.
// Trying to clip the left side of the map...
if(mapX < 0){
mapX++;
tileX = 0;
i+=iter;
continue;
}
So, the broken section, as we determined, that the mapX can’t find the values between -1 and 0 (as such -0.5 etc…)
__inline_cpp__("
// Get tile ID from the map. Then use that to find the tile itself from the tileset
auto tileId = ((uint8_t*)tileMap)[mapX + mapY];
auto tile = ((uint8_t*)tileSet) + tileId * 256 + tileY;
");
This is where we actually use the values previously collected to get first the Tile ID from the map and then using that tile ID we get the actual Tile (which is an array of color indexes).
// Loop over the Tile color IDs and put them in the line array.
for(int t = 0; t < iter; t++){
__inline_cpp__("
color = tile[tileX + t];
");
line[i+t] = palette[color];
}
With the tile, we loop (with that iter variable so we know how many to put in the line) over the tile to populate the line with the correct color from the palette.
i+=iter;
tileX = 0;
mapX++;
}
}
and finally we increment to do the same thing again on the next tile in the row.
This may be entirely obvious for most, but breaking it up I hope helps explain a bit on my mental process of what’s happening.
This is when things are about to get good