C# woes

A place for your artistic side. Discuss techniques and tools for pixel art on the NES, GBC, or similar platforms.

Moderator: Moderators

User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: C# woes

Post by Dwedit »

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.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Jsolo
Posts: 27
Joined: Mon Jun 27, 2011 4:14 am
Location: Lurker Cave

Re: C# woes

Post by Jsolo »

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 :)
snarfblam
Posts: 143
Joined: Fri May 13, 2011 7:36 pm

Re: C# woes

Post by snarfblam »

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.
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.

Also, am I the only one who uses 8-bit formats to take advantage of the ability to change palettes?
Jsolo
Posts: 27
Joined: Mon Jun 27, 2011 4:14 am
Location: Lurker Cave

Re: C# woes

Post by Jsolo »

snarfblam 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.
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 :)
snarfblam wrote:Also, am I the only one who uses 8-bit formats to take advantage of the ability to change palettes?
I do that too ;)
snarfblam
Posts: 143
Joined: Fri May 13, 2011 7:36 pm

Re: C# woes

Post by snarfblam »

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 :)
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.

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.
zkip
Posts: 67
Joined: Tue Nov 20, 2012 1:59 pm

Re: C# woes

Post by zkip »

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:

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);
            
        }
NesTileDrawing is Dwedit's code from a couple posts back.

Thanks.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: C# woes

Post by Dwedit »

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!
zkip
Posts: 67
Joined: Tue Nov 20, 2012 1:59 pm

Re: C# woes

Post by zkip »

This is working amazingly now.. Thank you :D 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. :?
Post Reply