back again MotZilla. i tried to follow your advices, but i'm still having problems with the background rendering.
i'll let my code explain it for me, since i consider it's self explanatory. my apologize in advance if someone considers that i'm being insulting by doing this. no intention to get pissed anybody. i'm not being lazzy, it's just sometimes it's not easy when you are a non-native english speaker. so "go take an english class" are going to be consider a constructive reply XD
this is my emulator's main loop:
Code: Select all
while(CPU_Running )
{
if(Scanline < 240) // the active scanlines
{
RunScanline(); // draw a single scanline
Scanline++; // increment the scanlines counter
}
else if(Scanline < 262) // the VBlank scanlines
{
PPU_2002 |= 0x80; // tell the game we're in VBlank so it can execute code
Scanline++; // increment the scanlines counter
CyclesCPU -= 114; // decrement the CPU cc's counter
while(CyclesCPU <= 114) // execute 114 CPU cc's
{
OpCode = RAM[PC]; // fetch opcode
EjecuarOpCode(OpCode); // execute opcode
CyclesCPU += CyclesTable[OpCode]; // increment the CPU cc's counter
}
}
else if(Scanline == 262) // if it's the last scanline, reset the scanlines counter
{
Scanline = 0;
}
}
and this is my (so very basic) ppu engine:
Code: Select all
void RunScanline()
{
int i, j, Y;
byte NT_Entry, PT_Entry_Low, PT_Entry_High;
word PT_Addr, NT_Addr;
byte ColorBit0, ColorBit1, ColorIndex;
if(Scanline == 0) // the dummy scanline
{
// TODO. Nothing here yet...
}
else if((Scanline > 0 ) && (Scanline <= 240)) // the active scanlines
{
switch(READ_BIT(PPU_2000,4)) // fetch base pattern table address
{
case 0: PT_Addr = 0x0000; break;
case 1: PT_Addr = 0x1000; break;
}
switch(PPU_2000 & 0x3) // fetch base name table address
{
case 0: NT_Addr = 0x2000; break;
case 1: NT_Addr = 0x2400; break;
case 2: NT_Addr = 0x2800; break;
case 3: NT_Addr = 0x2c00; break;
}
for(i = 0; i < 32; i++) // the basic background drawing loop
{
NT_Entry = VRAM[NT_Addr + i]; // fetch tile number
Y = (Scanline - 1) % 8; // fetch tile byte-line number
PT_Entry_Low = VRAM[PT_Addr + (NT_Entry * 16) + Y]; // fetch the lower sliver from the pattern table
PT_Entry_High = VRAM[PT_Addr + (NT_Entry * 16) + Y + 8]; // fetch the upper sliver from the pattern table
Y++; // increment the tile byte-line number
for(j = 7; j >= 0; j--) // render the 1x8 pixel sliver of the tile
{
ColorBit0 = READ_BIT(PT_Entry_Low,j); // fetch the lower color bit
ColorBit1 = READ_BIT(PT_Entry_High,j); // fetch the upper color bit
ColorIndex = (ColorBit1 << 1) | ColorBit0; // combine the color bits into a pallete index
switch(ColorIndex) // render a single pixel
{
case 0: putpixel(screen,(i * 8) + ((j * (-1)) + 7),Scanline - 1,COLOR_0); break;
case 1: putpixel(screen,(i * 8) + ((j * (-1)) + 7),Scanline - 1,COLOR_1); break;
case 2: putpixel(screen,(i * 8) + ((j * (-1)) + 7),Scanline - 1,COLOR_2); break;
case 3: putpixel(screen,(i * 8) + ((j * (-1)) + 7),Scanline - 1,COLOR_3); break;
}
}
}
}
return;
}
as you can see, there's no attribute table data implementation yet.
after that, this is what the screen shows up (the game is Donkey Kong Jr, but the i'm getting the same crappy results on every game):
and after a little while, that image turns into this one:
i tryed it by setting the register $2002 to 0 at startup, and by setting the bit #7 to 1, and by setting the bit #7 to 0, and there's no difference between one way or another. it shows the same images or either nothing.
by the way, i'm setting the bit #7 of $2002 every time the game reads from it, as NESTECH says. also, there's no implementation of scrolling yet in my emu. maybe i'm too stupid but i really don't understand Loopy's document, wich seems has to very important. anyway, there's no scrolling in the game's background that i'm testing my emu with (at least in the title screen). or maybe i'm wrong? there's scrolling and that's way i'm not showing the tiles correctly?
since all the tiles that comes up to screen are the same, it's clear that i'm not fetching the tile address correctly, or i'm fetching it in wrong a moment. also, i tried it by executing some game code for the first 20 scanlines before the program goes into the main loop, so it have enough time to modify the VRAM and set up the background, but nothing changed.
this is getting me so frustrated... i'm spending hours and hours in coding, reading and changing things into my program, but all i'm getting is my head hitting the wall. oh lord have mercy! XD
i'm not asking for code, i'm just looking for someone to shed some light here. any reply will be highly apreciated.
peace out!
EDIT: just in case, this is what FCEUXDSP Name Table viewer show:
so gues yeah... i'm totally fetching the tiles from anywhere but the VRAM
