Allegro 5 vs 4: Advantages and Reasons for Switching, Drawbacks?
DarkApothecary

Hello Allegro developers / programming hobbyists / other fellow Human beings. Last semester I spent some time developing a turn-based strategy game with Allegro 4. I found Allegro 4 more than capable for what I was attempting to do, and ended up running the program smoothly on my rather s***y ("of poor quality") laptop.
I will soon be setting out to make a second game, this one intended to be in a top-down 'Gameboy Advance,' style: somewhere between Pokemon Red/Blue and GBA's "Harvest Moon: Friends of Mineral Town." In other words, lots of animation.
Before I embark once more, however, I want to make sure I'm using the proper tools. My questions comes down to: what are the reasons for upgrading to 5? Does it allow you more freedom or less? What are the limitations of 4? Of 5? Is the event-driven system refined to the point where Allegro 5 is really better than Allegro 4? What was lost in the transition, if anything?
Essentially, I'm asking experienced persons: which do you prefer, and why?
I'd really appreciate anyone's thoughts on any of this.

Sincerely,
DarkApothecary (Really LightApothecary, but Dark just sounded so much cooler)

wombat

Hi DA, I've just ported my code from A4 to A5 so I can give you some info on my experience between the two.

- Framework:
A5 is definitely better than A4 in terms of the framework. It's the reason I switched to A5. The addons also provide a much more integrated way of using things like PNG and JPEG files, and the use of video memory for bitmaps is invaluable.

- Performance:
Unfortunately A4 was faster as a whole for me. Using A4 my game was running at 100 fps pretty much all the time. Even with 32-bit bitmaps, 750,000 objects floating around space, and pixel perfect (PP) collision turned on I was rarely dropping below 80 fps (on an old Core 2 Duo E6600).

After porting to A5 I now notice my frame rate drops a lot. The most severe drop is when I have to do per-pixel checks during PP collision tests. With A4 I can do 100 missiles against 10 enemies and fall to about 80 fps. With A5 it drops to 35 fps.

I admit that part of this might be my misunderstanding of how to use A5's pixel operations. However I think I've got it mostly optimised as pixel perfect collision for 100 missiles VS 10 enemies would be even slower if I was using A5's graphics routines incorrectly. So I think it's just that A5 isn't as suitable for low level pixel operations. (As a note, on the first day that I ported my code I didn't realise I should lock bitmaps before doing per-pixel ops or direct memory access on bitmaps....now that was a major drop in frame rate!).

I may still be missing some other optimisation required for A5 but the point is I didn't need to do any of this when using A4. The per-pixel code just ran better. I want to keep using A5 so I'm at the point where I think I'll have to use primitive vertices for collisions instead.

I should note that other bitmap drawing, particularly doing translucency, is much faster in A5. So if you don't plan on using many per-pixel operations in your game A5 is definitely nicer.

- Capabilities

I think A5 sacrifices some performance for greater flexibility and capability. I certainly prefer A5's graphic routines over A4s. I mean, what was with having a masked_blit and draw_sprite, but only one doing translucent blending?

Similarly, I really like A5s framework support. Things like events and timers are very nice to have. My own code had all that working but using Allegro's events makes things much cleaner.

Overall I prefer A5. My only problems so far are the performance hit for per-pixel operations, and TrueType fonts not rendering correctly (at least not how I expect them to). I can live with those two problems as the performance issue remedied by defining primitive vertices for my objects and doing collisions on those rather than pixels, and the TTF problem I'll likely end up just porting my old A4 TTF code.

The fact that A5 has proper shader support is the big one for me. It's the major reason I moved to A5.

If you are choosing between A4 and A5 I'd recommend A5, if only because A4 likely to become obsolete in a couple of years.

Evert
wombat said:

I admit that part of this might be my misunderstanding of how to use A5's pixel operations. However I think I've got it mostly optimised as pixel perfect collision for 100 missiles VS 10 enemies would be even slower if I was using A5's graphics routines incorrectly. So I think it's just that A5 isn't as suitable for low level pixel operations. (As a note, on the first day that I ported my code I didn't realise I should lock bitmaps before doing per-pixel ops or direct memory access on bitmaps....now that was a major drop in frame rate!).

Reading pixels from a texture is slow. If you use memory bitmaps, it shouldn't really be any slower.
Having said that, for doing pixel-perfect collisions, Allegro bitmaps aren't the best data-structure anyway. You're better off making bitmasks for your sprites and using those.

wombat
Evert said:

Having said that, for doing pixel-perfect collisions, Allegro bitmaps aren't the best data-structure anyway.
You're better off making bitmasks for your sprites and using those.

In A4 I used unsigned char pointers and did XOR masking between lines of the bitmaps. It resulted in very fast pixel-perfect testing.

I think I've just figured out a fast(er) way to do it in A5....since I'm now doing it purely on the alpha component (bits 24 - 31 of every pixel) I can take the locked data and use pointers to read and compare every 4th byte for the test. When I ported to A5 I tried doing it with A5's unmap_rgba() function because I wanted to use the API calls. Unfortunately I think that's where I'm taking the hit. Changing to this new method should be much faster.

psycho

You shouldn't compare the bitmap data themselves when using Allegro (generally, you shouldn't do that at all if the source data is stored in video memory). Even when you lock your data properly, you still end up transferring the whole bitmap from VRAM to RAM each time you lock the surface.

Rather, you should store a separate copy of your surface in system memory. Or rather, just a 1-bit version which marks which parts of the tile are solid and which aren't.
This actually has the advantage that processing itself is faster as well - you can process 32 or 64 (depending on the host architecture) row pixels at once!

(This is basically what Evert said as well, I just felt like having my yearly post on A.cc now :P)

EDIT:
Oh well, and totally off topic actually. I'll comment on my experiences when moving from A4 to A5 tomorrow ;)

wombat
psycho said:

You shouldn't compare the bitmap data themselves when using Allegro (generally, you shouldn't do that at all if the source data is stored in video memory). Even when you lock your data properly, you still end up transferring the whole bitmap from VRAM to RAM each time you lock the surface.

I only ever lock them once, right after they've been loaded and indexed. They then stay locked as they are purely read-only (I never write to them). The VRAM version never gets updated (as it never changes, and is never unlocked). It works very fast right now. The speed hit, from profiling, comes from all the al_unmap_rgb calls.

Thomas Fjellstrom

I think locking a bitmap causes allegro to use it's software bitmap drawing, so there's probably a hit there.

jmasterx
wombat said:

The speed hit, from profiling, comes from all the al_unmap_rgb calls.

Why not just do:

ALLEGRO_COLOR c;
float alpha = c.a;

and just compare floating point values?

wombat

I think locking a bitmap causes allegro to use it's software bitmap drawing, so there's probably a hit there.

Interesting. I'll have to check that (looks like it's time for me to go through the A5 source).

However if that's the case I haven't noticed the hit as my frame rate went up considerably after indexing the bitmap, locking it, and then using it without unlocking. It's loaded as a video bitmap so I was under the impression locking it placed a copy in memory but the VRAM version is the one that gets blitted as the lock was READONLY. At least according to the Allegro 5 docs a READONLY lock doesn't require any changes to the VRAM version.

psycho said:

Rather, you should store a separate copy of your surface in system memory. Or rather, just a 1-bit version which marks which parts of the tile are solid and which aren't.

The 1-bit version is what you save on disk. In memory it still unpacks into a 32-bit bitmap.

jmasterx said:

Why not just do:
ALLEGRO_COLOR c;
float alpha = c.a;

That still requires reading all 4 bytes of each pixel (to fill the ALLEGO_COLOR struct). Using direct pointer arithmetic I can do the tests by just reading 1 byte.

Apologies to the OP, I seem to have hijacked his thread! (I'll move this to a new thread if I find I need help with my collision code in the coming days).

Thread #607650. Printed from Allegro.cc