What's new

Game Boy

HyperHacker

Raving Lunatic
No... I'm talking about re-drawing the screen. How are you translating the GB's VRAM and tile map into an image scaled to the size of the window without massive slowdown?

Also just for comparison's sake, what kinds of CPU speeds are you all getting? I'm averaging around 250% with just the CPU core (IE no video, sound etc).
 

aprentice

Moderator
HyperHacker said:
No... I'm talking about re-drawing the screen. How are you translating the GB's VRAM and tile map into an image scaled to the size of the window without massive slowdown?

Also just for comparison's sake, what kinds of CPU speeds are you all getting? I'm averaging around 250% with just the CPU core (IE no video, sound etc).

The screen is rendered line by line, no scaling or stretching needed.
As for speed, it can greatly vary depending on your system specs and video card. My emu (with the graphics on) runs at 1400fps on someones pc who has a high end gfx card, while it runs like 700fps on mine with my crappy geforce3. Probably without the video it would run at like 3000 fps or something :p Before you go thinking your cpu is slow, i just want to say that mine is super optimized, I milked it for all its worth, I spent two weeks optimizing it (no joke).

On the side note, i started to attempt sound, i'm not exactly sure how to handle it really so its going to be a slow process. I already emulated the sound registers so its a matter of generating sound using the raw waveform pattern in memory. What baffles me is how to play sound, and how to use notifications via streaming in directsound.
 
Last edited:

zenogais

New member
Sound is tricky, but direct sound does have a raw waveform mode. So its just a matter of using the callback to load the latest sound data into DirectSound for playing. My guess is its probably a little more involved than that, but thats the basic gist of it from what I can gather.
 
Last edited:

aprentice

Moderator
zenogais said:
Sound is tricky, but direct sound does have a raw waveform mode. So its just a matter of using the callback to load the latest sound data into DirectSound for playing.

do you have any resources on its waveform mode? Not many sound tutorials on the web (not interested in openal or fmod tutorials).
 

zenogais

New member
well, for the WAVEFORMATEX structure you probably wanna use WAVE_FORMAT_PCM with two channels. That should get you started. Now I'm not an expert on this stuff, but since it has only two channels of sound it shouldn't be terribly difficult to emulate.
 

bcrew1375

New member
HyperHacker, could you make yourself more clear? Are you talking about making the screen bigger than 160x144? Like scaling it to 2 or 3 times bigger? If so, you would just draw a rectangle instead of a single pixel. I'm not sure if that's what you're talking about or not :p.
 

aprentice

Moderator
bcrew1375 said:
HyperHacker, could you make yourself more clear? Are you talking about making the screen bigger than 160x144? Like scaling it to 2 or 3 times bigger? If so, you would just draw a rectangle instead of a single pixel. I'm not sure if that's what you're talking about or not :p.

hey bcrew, how'd that line by line implementation go? also, have you looked into sound?
 

bcrew1375

New member
I wish I could say I have it working, but my brain just doesn't seem to want to work right now :/. I can't get myself to comprehend the code at the moment. I rewrote my background code basing it on yours, but I'm still missing something, probably something really simple. I just can't figure out what. As far as sound, I'm not touching it until I get some of the other kinks worked out.
 

aprentice

Moderator
bcrew1375 said:
I wish I could say I have it working, but my brain just doesn't seem to want to work right now :/. I can't get myself to comprehend the code at the moment. I rewrote my background code basing it on yours, but I'm still missing something, probably something really simple. I just can't figure out what. As far as sound, I'm not touching it until I get some of the other kinks worked out.

send me your code for the drawing routine and i'll have a look and point you in the right direction
 

HyperHacker

Raving Lunatic
bcrew1375 said:
HyperHacker, could you make yourself more clear? Are you talking about making the screen bigger than 160x144? Like scaling it to 2 or 3 times bigger? If so, you would just draw a rectangle instead of a single pixel. I'm not sure if that's what you're talking about or not :p.
Yeah, I figured that much out. Still only getting ~70% speed though. (Yes, my video card does suck a lot. :p) The real problem is updating the tile graphics when a game writes to them, it seems to be causing some major slowdown. I finally got it to actually do something, Tetris gets to the title screen, w00t w00t. The biggest problem is I can't seem to work out this one damn graphic bug. On each tile, the right-most pixels are always drawn in colour 0.
angry.gif


Here's my crappy tile-updating code, you give it the tile # (just the address being modified \ 0x10, I call it whenever the game writes to the tile data).
Code:
void UpdateTile(unsigned int TileNum)
{
	unsigned int Addr = (TileNum << 4);
	if(LogInstructions) printf("UpdateTile %04X %02X, ---- - - -- --",Addr,TileNum);
	int x,y,c;
	for(y=0;y<8;y++)
	{
		for(x=0;x<8;x++)
		{
			if(LogInstructions) printf("##############%04X %01X %01X %02X %02X",Addr,x,y,GFX0[Addr],GFX0[Addr + 1]);
			c = ((GFX0[Addr + (y << 1)] >> x) & 1) |
			    ((GFX0[(Addr + (y << 1)) + 1] >> (x-1)) & 2);
			SetPixel(TileDC,(7 - x) + (TileNum << 3), y, Colour[BGColourIndex[c]]);
		}
	}
	if(LogInstructions) printf(" B");
	for(x=0;x<10;x++)
	{
		BitBlt(MainDC,0,x << 3,160,8,TileDC,x*160,0,SRCCOPY);
	}
	if(LogInstructions) printf(" OK\n");
}
(Small note: On the line that prints "##############", the #s are actually supposed to be backspace characters. I couldn't get the escape code to work so I just manually inserted them. Isn't TextPad great? :p)
The problem seems to be with the algorithm just before SetPixel. Somehow the right-most pixel is always coming up as color 0. (Also, yes, at the moment it's written to dump all the tiles to the screen instead of display the actual output, which is what that BitBlt loop at the end is for.)

Anyone else working on one of these, here's a tip: Instruction 0xCB is a lot more important than you'd think. :p

[edit] Hmm, I think I might know what's going on... X >> -1 = 0, rather than X << 1 like you would think. :blink:
 
Last edited:

bcrew1375

New member
I'm not sure about the color 0 thing, but I think you might be making the same mistake I did. You don't want to update the screen whenever the tile data changes. You need to update the screen using LY(memory location 0xFF44). When the LY changes, you draw the pieces of the tiles that are on that specific line, you don't want to draw the tiles all at once. I'm guessing this is the reason I have problems in Donkey Kong, Legend of Zelda, and Super Mario Land. You should have a routine to draw one scanline instead of one tile.
 

HyperHacker

Raving Lunatic
Interesting... I had just had it drawing the entire screen when it hits vblank. The problem isn't really re-drawing the screen, it's drawing each individual tile onto a buffer.

Is there a faster method than SetPixel/BitBlt though?
 
Last edited:

aprentice

Moderator
HyperHacker said:
Interesting... I had just had it drawing the entire screen when it hits vblank. The problem isn't really re-drawing the screen, it's drawing each individual tile onto a buffer.

Is there a faster method than SetPixel/BitBlt though?

If you render the whole screen at vblank, you WILL have problems, and also remember there are dynamic scrolling registers. I think your code is slow cause you are rendering "per tile", how often is this routine called?
 

HyperHacker

Raving Lunatic
There are 2 different routines. One draws each individual tile onto a buffer, this is called whenever the game writes to the tile data in order to update the buffer (it re-draws whatever tile was modified). The other copies each tile to the screen as specified in VRAM and is called every time it enters Vblank. I am going to change it to draw per scanline instead of all at once though. (I'd completely forgotten about the scroll registers. ^_^; )
 

bcrew1375

New member
You know, I finally got my scrolling code to work, thanks to VBA's source. I couldn't seem to grasp it until I looked there. The only thing is now I kinda feel like a theif because my graphics code is heavily based on VBA's. :plain: BTW, thanks for your help, aprentice. Now I can concentrate on the CPU bugs :).
 
Last edited:

aprentice

Moderator
bcrew1375 said:
You know, I finally got my scrolling code to work, thanks to VBA's source. I couldn't seem to grasp it until I looked there. The only thing is now I kinda feel like a theif because my graphics code is heavily based on VBA's. :plain: BTW, thanks for your help, aprentice. Now I can concentrate on the CPU bugs :).

no problem, cpu bugs are the easy part to fix, timing is a huge pain :p
I cant get the timing right in my emu, its killing compat :plain:
 

Dark Stalker

New member
Hi!

I've been lurking around the outskirts of these forums for some years now, looks like quite a few interesting things have been happening here lately.

Y'all got me throwing away the last few weeks starting my own cross-platform gb emu. I've gotten to the point where things start to look like something playable. I've been spending the night implementing MBC1, which seems to do fairly well (Zelda looks quite playable except for the obvious lack of sprites). I guess I'll be looking at sprites next if I get some more time on my hands.


Screenies:
Big Scroller Demo
skjermbilde119.png
skjermbilde1111.png


Super Mario Land
skjermbilde117.png


Link's Awakening
skjermbilde115.png
skjermbilde114.png
 

aprentice

Moderator
nice work indeed, its good to see more people who read this thread successfully attempting their own gameboy emu.

Have you completed the timing for your emulator yet?
 

Dark Stalker

New member
I've still got ways to go before I (if ever) catch up to you guys I think. Sprites are coming along nicely though. Zelda's been complaining about some weird drawing problem I have, effectively killing the bottom-screen menu. Is this an issue with the window-drawing you think? The menu won't show if the start button is pressed either for that matter. I've got a few games acting similarly grumpy too, though I haven't done a lot of testing yet.

skjermbilde1113.png
skjermbilde1112.png



As for timing, I've got the timer and divider registers presumably working, and I'm generating all the interrupts except for input which doesn't seem to make any difference to any rom I've tested yet anyway. I'm also supposedly drawing every line at the correct time, but I'm only setting vsync and hsync modes (will setting the other ones do anything for compatibility?). Additionally, I think I've got the wrong cycle-numbers for some of the conditional opcodes, and probably a few of the others too. There's probably more aspects to timing that I haven't even begun to think of yet.
 

Top