I use nes.lib and wrote a simple function to detect collision. But there's something wrong that my player could stutter through the wall, here's my main code:
unsigned char CheckCollision(unsigned char x, unsigned char y)
{
vram_adr(get_ppu_addr(NAMETABLE_A, x, y));
vram_read(&tile, 1);
vram_adr(NAMETABLE_A);
if(tile == 0xE0 || tile == 0xE1 || tile == 0xF0 || tile == 0xF1)
{
//if wall
return 1;
}
else
{
return 0;
}
}
You don't want to read from the PPU to determine collision. Especially you don't want to read from the PPU outside of v-blank.
Also. A read from the PPU ( vram_read function ) works differently than you would expect, and the first read from the PPU will return a "garbage" value. Every subsequent read will be a real value. So you need to read twice (to get 1 byte... read 3 times to get 2 bytes... etc)
And again, this is not what you should do for collisions. I recommend that you have a map of the room, in some compressed format, in the ROM (or RAM) that you read from... because, as I stated above, you shouldn't read from the PPU outside of v-blank. Also, setting a PPU address ( vram_adr function ) can mess up the scroll registers, if you don't undo it before the frame starts rendering.
...and if you do it while the frame is rendering (outside of v-blank), this might not work at all in a real hardware. It would fail 100% of the time.
Edit...
So, what you want is a constant array of values that represents the layout of the room. I prefer a 1 byte per 16x16 square of the room, so that you fit 16 wide nicely and you can do some bit shifting of X and y to get a collision byte like (binary) yyyyxxxx.
Apparently, vram_read does a dummy read for you, I forgot. You do not need an extra.