Fiddle to the bittle

I've added two new routines to the bit-trick page: 1→4 bit-unpack with reverse and bit reversals. This last one is elegant … except for one bit of C tomfoolery that is required to get GCC to produce the right ARM code. I hope to discuss this in more detail later.

I've also added a new document about dealing with bitfields. It explains what to do with them, gives a few useful functions to get and set bitfields, and demonstrates how to use the C construct for bitfields. It also touches briefly on a nasty detail in the way GCC implements bitfield that can cause them to fail in certain GBA/NDS memory sections. If you're using bitfields to map VRAM or OAM, please read.

tonc 1.4 preview

I'm close to releasing the latest (and probably last; this really has gone on long enough) version of Tonc. As a preview, I'm releasing the PDF a little early in the hope that someone may take a look and offer some feedback before the official release (aw, c'mon, it's only 400 pages).

The changes mostly relate to the new Tonc Text Engine, a text system for all occasions. There's a new chapter describing how TTE works, how to write general character printers for (almost) for arbitrary sized fonts and every type of graphics, and a few other things. It's fairly long and could use sanity checking from someone else.

Also, many of the older demos now use TTE for their text as well. As a result they look cleaner and prettier, but it's possible there are some left-overs from older versions. So have at it.

Surface drawing routines.

I've been building a basic interface for dealing with graphic surfaces lately. I already had most of the routines for 16bpp and 8bpp bitmaps in older Toncs, but but their use was still somewhat awkward because you had to provide some details of the destination manually; most notably a base pointer and the pitch. This got more than a little annoying, especially when trying to make blitters as well. So I made some changes.


typedef struct TSurface
{
    u8  *data;      //!< Surface data pointer.
    u32 pitch;      //!< Scanline pitch in bytes (PONDER: alignment?).
    u16 width;      //!< Image width in pixels.
    u16 height;     //!< Image width in pixels.
    u8  bpp;        //!< Bits per pixel.
    u8  type;       //!< Surface type (not used that much).
    u16 palSize;    //!< Number of colors.
    u16 *palData;   //!< Pointer to palette.
} TSurface;

I've rebuilt the routines around a surface description struct called TSurface (see above). This way, I can just initialize the surface somewhere and just pass the pointer to that surface around. There are a number of different kinds of surfaces. The most important ones are these three:

  • bmp16. 16bpp bitmap surfaces.
  • bmp8. 8bpp bitmap surfaces.
  • chr4c. 4bpp tiled surfaces, in column-major order (i.e., tile 1 is under tile 0 instead of to the right). Column-major order may seem strange, but it actually simplifies the code considerably. There is also a chr4r mode for normal, row-major tiling, but that's unfinished and will probably remain so.
surface.gba movie
Demonstrating surface routines for 4bpp tiles.

For each of these three, I have the most important rendering functions: plotting pixels, lines, rectangles and blits. Yes, blits too. Even for chr4c-mode. There are routines for frames (empty rectangles) and floodfill as well. The functions have a uniform interface with respect to surface-type, so switching between them should be easy were it necessary. There are also tables with function pointers to these routines, so by using those you need not really care about the details of the surface after its creation. I'll probably add a pointer to such a table in TSurface in the future.


Linkies


The image on the right is the result of the following routine. Turret pic semi-knowingly provided by Kawa.

void test_surface_procs(const TSurface *src, TSurface *dst,
    const TSurfaceProcTab *procs, u16 colors[])
{
    // Init object text
    tte_init_obj(&oam_mem[127], ATTR0_TALL, ATTR1_SIZE_8, 512,
        CLR_YELLOW, 0, &vwf_default, NULL);
    tte_init_con();
    tte_set_margins(8, 140, 160, 152);

    // And go!
    tte_printf("#{es;P}%s surface primitives#{w:60}", procs->name);

    tte_printf("#{es;P}Rect#{w:20}");
    procs->rect(dst, 20, 20, 100, 100, colors[0]);

    tte_printf("#{w:30;es;P}Frame#{w:20}");
    procs->frame(dst, 21, 21, 99, 99, colors[1]);

    tte_printf("#{w:30;es;P}Hlines#{w:20}");

    procs->hline(dst, 23, 23, 96, colors[2]);
    procs->hline(dst, 23, 96, 96, colors[2]);

    tte_printf("#{w:30;es;P}Vlines#{w:20}");
    procs->vline(dst, 23, 25, 94, colors[3]);
    procs->vline(dst, 96, 25, 94, colors[3]);

    tte_printf("#{w:30;es;P}Lines#{w:20}");
    procs->line(dst, 25, 25, 94, 40, colors[4]);
    procs->line(dst, 94, 25, 79, 94, colors[4]);
    procs->line(dst, 94, 94, 25, 79, colors[4]);
    procs->line(dst, 25, 94, 40, 25, colors[4]);

    tte_printf("#{w:30;es;P}Full blit#{w:20}");
    procs->blit(dst, 120, 16, src->width, src->height, src, 0, 0);

    tte_printf("#{w:30;es;P}Partial blit#{w:20}");
    procs->blit(dst, 40, 40, 40, 40, src, 12, 8);

    tte_printf("#{w:30;es;P}Floodfill#{w:20}");
    procs->flood(dst, 40, 32, colors[5]);
    tte_printf("#{w:30;es;P}Again !#{w:20}");
    procs->flood(dst, 40, 32, colors[6]);

    tte_printf("#{w:30;es;P;w:30}Ta-dah!!!#{w:20}");

    key_wait_till_hit(KEY_ANY);
}

// Test 4bpp tiled, column-major surfaces
void test_chr4c_procs()
{
    TSurface turret, dst;

    // Init turret for blitting.
    srf_init(&turret, SRF_CHR4C, turretChr4cTiles, 128, 128, 4, NULL);

    // Init destination surface
    srf_init(&dst, SRF_CHR4C, tile_mem[0], 240, 160, 4, pal_bg_mem);
    schr4c_prep_map(&dst, se_mem[31], 0);
    GRIT_CPY(pal_bg_mem, turretChr4cPal);

    // Set video stuff
    REG_DISPCNT= DCNT_MODE0 | DCNT_BG2 | DCNT_OBJ | DCNT_OBJ_1D;
    REG_BG2CNT= BG_CBB(0)|BG_SBB(31);

    u16 colors[8]= { 6, 13, 1, 14, 15, 0, 14, 0 };

    // Run internal tester
    test_surface_procs(&turret, &dst, &chr4c_tab, colors);
}

Expelled recap

So this Expelled movie has been out for a couple of weeks now. To my surprise, it's been doing rather well. It's running in about 400 theaters right now, which I guess is a lot (but then I'm from a puny little country so I could be wrong). It's also got an amazing rating of 9 on rotten tomatoes.

Oh, wait. That's not 9 out of 10; that's 9 out of 100. Wow. That's … that's just … wow.

So yeah, this thing is going down so hard it could go straight through the planet. A score of 9%. That should qualify as “Epic Fail” in anyone's book Anyone sane, anyway. As for the theater count, the guys at Panda's Thumb have been tracking the numbers; it started with just over 1000 on April 18th and is now down to 400. It'll probably disappear completely in a week or two.

Away from the silver screen, the producers and Ben Stein have been doing interviews left and right and apparently making complete asses of themselves. I've seen some videos of Stein that are just two-hands facepalmingly stupid. One of the things he's keen on mentioning is how Darwinism doesn't explain the origins of life or gravity or where the universe came from. The theory of evolution is not and will never be about those things, so why this counts as a mark against the theory I don't know. It's like to arguing that metallurgy doesn't explain last week's weather, therefore it's bogus. Simply using this line of reasoning hows that he really doesn't know what he's talking about. That, or he's deliberately misleading everyone, which is also a real possibility.

The real moment of inanity, however, comes from an interview at TBN where he made this immortal statement (emphasis mine):

Love of God and compassion and empathy leads you to a very glorious place, and science leads you to killing people.

O_O. Lolwut ?!?

Yes, he actually said that, and in all earnest too, apparently. You can see it (and a response to it) in Thunderfoot's latest Why do people laugh at creationists video. The original interview can be found here as well. This is what as also earned him the dubious virtue of second place for MSNBC's Worst Person in the World.

Right now, I am this close to believing this is actually all part of a massive hoax. With the ever-growing list of stupidities, I find it harder and harder to believe they're serious.


And now for something completely related: the infamous Beware the believers video. This *wonderful* clip was released anonymously in the end of March and has been a favorite in sciency circles since. There has been a lively debate about its origins. Because it clearly is caricaturing the atheists depicted in the clip (“if I was dyslexic, Id even hate dog too”. Hehehehe), one group believed the Expelled group were behind it. On the other hand, it was well done and extremely funny. Since the creationists have a long track record of shoddy craftsmanship and witlessness (the Expelled movie itself is a good example of this), many others felt it could not come from them.

About a month later, the answer came: it was done by Michael Edmondson, as a contract job for the producers of Expelled. So yes, it did come from their camp after all. That said, Edmonson isn't affiliated with them that much. I've read that the producers' intent was for it to be viral advertising for the movie. I don't think that worked out too well, though, what with it being embraced by the atheist side as one of the pieces of Internet Win of this year.

Read the thread on pharyngula for extra details. Edmonson himself also makes an appearance in the comments, so you get it straight from the horse's mouth. Simon Owens also has an interview with him at bloggasm.com, so check that out as well for even more details.

Lastly, to Michael Edmonson and Matt Chandler (who did the lyrics): thank you for the hilarious video. We will watch your career with great interest.

Grit 0.8.1

Grit 0.8.1 is out now. I've made three somewhat small changes here. First, there was some trouble with shared palettes/tiles if there was no -O or -S option. “Trouble”, as in segmentation fault. This should now be fixed.

I've also reformatted the include guards from __FOO__ to GRIT_FOO_H. GCC uses that format for internal #defines and it is very territorial about such matters. So, say, when you have elf.png, GCC gets cranky because that would hide its own __ELF__, and guess who wins out there? Again, thanks for pointing these things out, Quirky.

The last item is the addition of column-major tiling. This can be useful for horizontal scrolling games, since the data or the columns are all adjacent instead of a whole scanline apart. A second benefit of this mode is that rendering to tiles is made considerably easier (and a little bit faster too).

In case you hadn't noticed yet, I've also put the manual on-line. This shows the basic options for grit and wingrit, and now there's a description of how to use it in makefiles as well. This includes how the building the grit-demo project works. This one's quite interesting, so please check it out.


Project link.