I seem to have my PPU working more or less properly now, but it's making my emulator run bloody slow. I know it's the drawing because things speed up when I have it draw every other scanline (and further on down form that). Currently, every PPU clock I draw to an offscreen buffer (using SetPixel) the BG and sprite pixels that need to be drawn. At the beginning of vsync I then BitBlt that to the window. Now I'm almost positive that SetPixel is the bottleneck, so I ask what are better ways. I've thought of just writing the palette value to an array of unsigned integers representing the screen and then drawing that at vsync and if possible just memcpy this data into the DC (or something similiar). Any suggestions are welcome. Thanks
Doing what I said above (about the raw pixel array) certainly helped (and I used the following bit of code for getting it on the screen for anybody's who's interested):
SetBitmapBits (h_Bitmap, 0x40000, &a_Screen);
hDC = GetDC (h_Window);
BitBlt (hDC, 0, 0, 256, 240, h_Buffer, 0, 0, SRCCOPY);
ReleaseDC (h_Window, hDC);
It's still slow, but an improvement.
You can get a significant improvement by switching from GDI drawing routines to using DirectDraw. It does take a bit of an investment, though...
Quietust wrote:
You can get a significant improvement by switching from GDI drawing routines to using DirectDraw. It does take a bit of an investment, though...
Ditto on that. I couldn't believe it when I saw you using the GDI. DirectDraw is the choice for you, and it is really easy to setup.
Quietust, Investment?
Investment: for someone who's new to DirectX, yes.
I am in no way shape or form new to DirectX (in C++, perhaps, but not the API itself). I knew I would have to move that way at some point, so I guess I shouldn't delay the inevitable
. The only reason I was using GDI in the first place was because it's simple and it worked while I completed my CPU/PPU, but everything being so slow kind of hinders that
. Thanks for the input.
The Allegro library is a cross-platform wrapper around DirectX and other PC platforms' counterparts, which may make it easier to get an array where you can render pixels.
tepples wrote:
...which may make it easier to get an array where you can render pixels.
In what way?
IIRC, locking a surface will return a pointer to the memory location with the image data (standard ddraw procedure).
How much faster is it than DirectDraw's Lock? If there is no significant speed increase then it might be a good idea to stick with DirectDraw. If we all use the same language then we can all help each other out more. Hey, we all speak english after all...
on zophar, i find visualBasic 6 code of a nes emu. It use GDI, one guy made source for a bitBltFast routine, it render graphics good and fast!. take a look on zophar.
yep direct draw is best.. but take a look on zophar for this good use of GDI.
WedNESday wrote:
How much faster is it than DirectDraw's Lock?
If you don't already have Windows, or your customers don't already have Windows, then learning to use SDL or Allegro is faster than flipping burgers to buy a copy of Windows for yourself and each customer.
I had considered SDL too, but I've had speed problems with it before.
EDIT:
Code:
unsigned long *g_Screen = (unsigned long *) g_Ddsd.lpSurface;
memcpy (g_Screen, &a_Screen, sizeof (unsigned long) * 0x10000);
I'd love to see anything make it simpler than that
Switching to DirectDraw didn't help speed much, though.