Here's something I quickly whipped up:
http://pastebin.com/DVYrxjJv
I decided to throw everything into a class called "NesTileDrawing" just to pass less parameters to the draw function.
C# woes
Moderator: Moderators
Re: C# woes
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: C# woes
Note that rectangle copies aren't the slow part in anything what you're doing; SetPixel is the culprit as it checks the range of x and y every time and needs to compute the array index every time, too.
Dwedit's code is a way to do it, although I prefer decoding individual tiles and storing them in a List<Bitmap>, as I can easily reorder tiles and tile display as much as I like (e.g. 3 tiles per row or 4 tiles per column). Decoding like in his code is undefined IIRC, because the image stride (line width) doesn't always have to be the same as width*sizeof(pixel). In this case it should work out though
Dwedit's code is a way to do it, although I prefer decoding individual tiles and storing them in a List<Bitmap>, as I can easily reorder tiles and tile display as much as I like (e.g. 3 tiles per row or 4 tiles per column). Decoding like in his code is undefined IIRC, because the image stride (line width) doesn't always have to be the same as width*sizeof(pixel). In this case it should work out though
Re: C# woes
Well... kinda. Accessing image data requires some preparation before and cleanup after. Using SetPixel causes prep and cleanup to occur for every single pixel, which is why it is incredibly slow. If you draw all of your images to a tile sheet and use Graphics.DrawImage to draw your images, you cut way down on redundant housekeeping, but Graphics.DrawImage is designed with flexibility as a priority over speed.Jsolo wrote:Note that rectangle copies aren't the slow part in anything what you're doing; SetPixel is the culprit as it checks the range of x and y every time and needs to compute the array index every time, too.
Also, am I the only one who uses 8-bit formats to take advantage of the ability to change palettes?
Re: C# woes
Surely you don't need optimized code that runs in 1ms instead of 5ms for an editing tool written in C#. I believe DrawImage is a way easier solution than writing your own blittersnarfblam wrote:. If you draw all of your images to a tile sheet and use Graphics.DrawImage to draw your images, you cut way down on redundant housekeeping, but Graphics.DrawImage is designed with flexibility as a priority over speed.
I do that toosnarfblam wrote:Also, am I the only one who uses 8-bit formats to take advantage of the ability to change palettes?
Re: C# woes
It depends on how much needs to be drawn and how often. I wrote my custom blitter for my Metroid level editor, initially because it made the program feel much more responsive when dragging objects on the screen. When I modified the program to show as many screens as will fit on your monitor, allowing you to scroll freely, that optimization became absolutely essential. And in my experience, the difference between DrawImage and a custom blitter for tile-based graphics is a little more dramatic that you realize. The difference was very noticeable even when the program only dealt with one screen at a time. Also, like I said, I use indexed image formats to allow the use of and changing of palettes. GDI+ cannot manipulate images that use an indexed format.Jsolo wrote: Surely you don't need optimized code that runs in 1ms instead of 5ms for an editing tool written in C#. I believe DrawImage is a way easier solution than writing your own blitter
However, while it is nice to have super-fast drawing code (or more flexible palette support), it usually isn't necessary. Especially if you're still learning. It's probably better in this case to focus on how to construct images from tiles rather than trying to write your own blitting code.
Zkip, maybe you should post the code that uses DrawImage. Like Jsolo said, the performace should be acceptable at the very least.
Re: C# woes
Erm, sorry for taking so long to get back.. I'm going through a 10 month break up now and time is creeping.. and I'm really confused about life but as they say it goes on, I reckon.
So, I've rewritten a few things, but Dwedit's code has really helped me along. I've moved the metatile struct to a constructor in a separate class. I'm still having trouble though :/ I have the full definitions I need in a byte array and I can't figure out how to put it all in a for loop to display them all. Any chances I could snag some help on this? Basically I put a metatile together and draw it like this:
NesTileDrawing is Dwedit's code from a couple posts back.
Thanks.
So, I've rewritten a few things, but Dwedit's code has really helped me along. I've moved the metatile struct to a constructor in a separate class. I'm still having trouble though :/ I have the full definitions I need in a byte array and I can't figure out how to put it all in a for loop to display them all. Any chances I could snag some help on this? Basically I put a metatile together and draw it like this:
Code: Select all
var gfxeditor = new NesTileDrawing(ROM.chrData, palette, pixels, 256);
MetaTile tilename = new MetaTile(0xa5,0xa6,0xa7,0xa8); <- need help here
DrawMetatile(tilename, 0, 0, gfxeditor);
Code: Select all
void DrawMetatile(MetaTile mt, int x, int y, NesTileDrawing source)
{
source.DrawTile(x, y, mt.topLeft);
source.DrawTile(x + 8, y, mt.topRight);
source.DrawTile(x, y + 8, mt.bottomLeft);
source.DrawTile(x + 8, y + 8, mt.bottomRight);
}
Thanks.
Re: C# woes
You looking for something like this?
Code: Select all
byte[] bytes = File.ReadAllBytes("metatiles.bin");
List<Metatile> list = new List<Metatile>();
for (int i = 0; i <= bytes.Length - 4; i += 4)
{
var newMetatile = new Metatile(bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]);
list.Add(newMetatile);
}
for (int i=0; i<list.Count; i++)
{
x = i % 16;
y = i / 16;
var metaTile = list[i];
metaTile.DrawMetatile(metaTile, x*16,y*16,source);
}
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: C# woes
This is working amazingly now.. Thank you Now I just need to figure out how to allow each tile it's own palette... I guess this is going to be a hardship? Involving heavily modifying the NesTileDrawing class?
I'm terribly sorry that I can't grasp this.. I hope I'm not too bad of an thorn.
I'm terribly sorry that I can't grasp this.. I hope I'm not too bad of an thorn.