A programmer friend of mine recommended I switch to SDL, after reading a bit about it and seeing that I can actually switch without too much trouble in configurating compilers and compiling libraries and stuff, I decided to see which one is better before coming to any decision.
So I ran a search for "allegro VS SDL" on these forums, and after reading all sorts of things I found this post that suggested a benchmark for comparing the two, and decided to run it myself.
I copy pasted the code, and modified it a bit since it made the program crash :S
I ended up with:
Allegro: (the allegro messages were to help me find out what was causing it to crash, which was the commented-out rand()s)
1 | /* |
2 | * BlitTest |
3 | * |
4 | * Created by Thomas Harte on 26/01/2006. |
5 | * Copyright (c) 2006 __MyCompanyName__. All rights reserved. |
6 | */ |
7 | #include <stdio.h> |
8 | #include <allegro.h> |
9 | |
10 | |
11 | int main(int argc, const char *argv[]) |
12 | { |
13 | BITMAP *garbage, *target; |
14 | |
15 | allegro_init(); |
16 | install_timer(); |
17 | install_keyboard(); |
18 | |
19 | set_color_depth(32); |
20 | if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)) |
21 | { |
22 | allegro_message("Error setting 320x200x8 gfx mode:\n%s\n", allegro_error); |
23 | return -1; |
24 | } |
25 | target = create_bitmap(SCREEN_W, SCREEN_H); |
26 | garbage = create_bitmap(32, 32); |
27 | srand(time(NULL)); |
28 | |
29 | clear_to_color(screen, 0); |
30 | int blits = 0, countedblits, countedseconds = 0; |
31 | time_t stime, etime; |
32 | |
33 | etime = time(NULL); |
34 | /* try and align to a second */ |
35 | do |
36 | { |
37 | stime = time(NULL); |
38 | } |
39 | while(etime == stime); |
40 | while(!key[KEY_ESC]) |
41 | { |
42 | //allegro_message("ASDF1"); |
43 | //int x, y; |
44 | |
45 | /*allegro_message("ASDF2"); |
46 | x = ((rand() >> 16) * 640) / (RAND_MAX >> 16); |
47 | allegro_message("ASDF2"); |
48 | y = ((rand() >> 16) * 480) / (RAND_MAX >> 16); |
49 | allegro_message("ASDF2");*/ |
50 | blit(garbage, target, 0, 0, 0, 0, garbage->w, garbage->h); |
51 | //allegro_message("ASDF2"); |
52 | blits++; |
53 | |
54 | |
55 | etime = time(NULL); |
56 | if(etime != stime) |
57 | { |
58 | countedblits = blits; |
59 | countedseconds++; |
60 | stime = etime; |
61 | |
62 | if(countedseconds == 30) |
63 | break; |
64 | } |
65 | |
66 | } |
67 | |
68 | printf("%d counted seconds, %d counted blits => %0.2f blits/second\n", countedseconds, countedblits, (float)countedblits / countedseconds); |
69 | |
70 | destroy_bitmap(garbage); |
71 | destroy_bitmap(target); |
72 | return 0; |
73 | } |
74 | END_OF_MAIN() |
And for SDL:
1 | /* Simple program: Create a blank window, wait for keypress, quit. |
2 | |
3 | Please see the SDL documentation for details on using the SDL API: |
4 | /Developer/Documentation/SDL/docs.html |
5 | */ |
6 | |
7 | #include <stdio.h> |
8 | #include <stdlib.h> |
9 | #include <string.h> |
10 | #include <math.h> |
11 | #include <time.h> |
12 | #include <fstream> |
13 | |
14 | #include <SDL\SDL.h> |
15 | |
16 | int main(int argc, char *argv[]) |
17 | { |
18 | /*std::fstream txtstream; |
19 | txtstream.open("Test.txt",std::fstream::trunc | std::fstream::in | std::fstream::out); |
20 | txtstream<<"I AM A TEST INDEED\n"; |
21 | return 0;*/ |
22 | Uint32 initflags = SDL_INIT_VIDEO; /* See documentation for details */ |
23 | SDL_Surface *screen, *garbage, *t, *target; |
24 | Uint32 videoflags = 0;//SDL_ANYFORMAT; |
25 | int done; |
26 | SDL_Event event; |
27 | |
28 | /* Initialize the SDL library */ |
29 | if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { |
30 | fprintf(stderr, "Couldn't initialize SDL: %s\n", |
31 | SDL_GetError()); |
32 | exit(1); |
33 | } |
34 | |
35 | /* Set 640x480 video mode */ |
36 | screen=SDL_SetVideoMode(640,480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF); |
37 | if (screen == NULL) { |
38 | fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); |
39 | SDL_Quit(); |
40 | exit(2); |
41 | } |
42 | |
43 | t = SDL_CreateRGBSurface(SDL_SWSURFACE, 32, 32, 32, 0, 0, 0, 0); |
44 | garbage = SDL_DisplayFormat(t); |
45 | SDL_FreeSurface(t); |
46 | |
47 | t = SDL_CreateRGBSurface(SDL_SWSURFACE, screen->w, screen->h, 32, 0, 0, 0, 0); |
48 | target = SDL_DisplayFormat(t); |
49 | SDL_FreeSurface(t); |
50 | |
51 | int blits = 0, countedblits, countedseconds = 0; |
52 | time_t stime, etime; |
53 | |
54 | etime = time(NULL); |
55 | /* try and align to a second */ |
56 | do |
57 | { |
58 | stime = time(NULL); |
59 | } |
60 | while(etime == stime); |
61 | |
62 | int x=0,y=0; |
63 | done = 0; |
64 | while ( !done ) { |
65 | SDL_Rect Pos; |
66 | |
67 | x++; |
68 | y++; |
69 | if (x>600) |
70 | x=0; |
71 | if (y>400) |
72 | y=0; |
73 | /*Pos.x = ((rand() >> 16) * 640) / (RAND_MAX >> 16); |
74 | Pos.y = ((rand() >> 16) * 480) / (RAND_MAX >> 16);*/ |
75 | SDL_BlitSurface(garbage, NULL, target, &Pos); |
76 | SDL_UpdateRect(target, x, x, y+garbage->w, y+garbage->h); |
77 | blits++; |
78 | |
79 | etime = time(NULL); |
80 | if(etime != stime) |
81 | { |
82 | countedblits = blits; |
83 | countedseconds++; |
84 | stime = etime; |
85 | |
86 | if(countedseconds == 30) |
87 | break; |
88 | } |
89 | |
90 | /* Check for events */ |
91 | /* while ( SDL_PollEvent(&event) ) { |
92 | switch (event.type) { |
93 | |
94 | case SDL_KEYDOWN: |
95 | case SDL_QUIT: |
96 | done = 1; |
97 | break; |
98 | default: |
99 | break; |
100 | } |
101 | }*/ |
102 | } |
103 | std::fstream txtstream; |
104 | txtstream.open("Test.txt",std::fstream::trunc | std::fstream::in | std::fstream::out); |
105 | txtstream<<countedseconds<<" counted seconds, "<<countedblits<<" counted blits => "<<((float)countedblits/countedseconds)<<" blits/second"; |
106 | printf("%d counted seconds, %d counted blits => %0.2f blits/second\n", countedseconds, countedblits, (float)countedblits / countedseconds); |
107 | |
108 | /* Clean up the SDL library */ |
109 | SDL_FreeSurface(garbage); |
110 | SDL_FreeSurface(target); |
111 | SDL_Quit(); |
112 | return(0); |
113 | } |
The results were quite surprising, considering the results reported in that thread;
SDL came up with "30 counted seconds, 185213878 counted blits => 6173795.93 blits/second", compared to allegro's 13361577 => 445385.9, ~13-14 times faster
Does this even make sense? Did I perhaps make a mistake?
(The test was run on Allegro 4.2.1 and the latest SDL if I'm not mistaken. On an Athalon 64 3000+ and a geforce 4 MX420)
My main beef with allegro is its poor performance, which means that any high-resolution games are impossible to make if you have many objects onscreen (when a dirty rectangle system just won't help), so this is quite interesting to me.
For hires games, hardware-accelerated is the way to go anyway, so why not switch to AllegroGL (and maybe OpenLayer)? It's not hard, and it's supported on virtually anything capable of decent hires performance anyway.
Also, Allegro is not made for cutting-edge performance, but rather for solid multiplatform programming with a relatively easy-to-use interface with decent performance. Since Allegro doesn't use any graphics hardware acceleration except the very basic ones (vram -> vram blits), you can't compare its performance to anything truly accelerated. OTOH, if you run that benchmark on an ancient machine, maybe even under MS-DOS, the outcome may be very different.
Well, first of all its mostly hires 2D games, nothing too complicated, but just clearing a 1280x1024 bitmap in allegro takes too long. (Not sure how much time it takes on SDL, but if its 15 times faster its definitely good).
Switching to AllegroGL however would require learning OpenGL, which is more complicated, and is a bit much for 2d games.
Also, I'm not really interested in multiplatform support since I can't compile my stuff under anything but windows anyway (I don't even have enough free room on my HD to dualboot), but even so I hear that SDL supports more OS's. (which is of course
irrelevant)
I don't know much about SDL, but I was under the impression that you can get "hardware surfaces" which allow hardware accelerated 2D drawing, which would be sufficient for 2D games.
Learning OpenGL ? With AllegoGL ?
Not really a need.
Check dumbtest:
1 | allegro_gl_set_allegro_mode(); |
2 | line(screen, 0, 0, 640, 480, makecol(0xff, 0, 0xff)); |
3 | triangle(screen, 115, 21, 150, 350, 5, 90, makecol(0xff, 0, 0)); |
4 | triangle(screen, 145, 21, 190, 350, 45, 90, makecol(0, 0, 0xff)); |
5 | triangle(screen, 205, 21, 240, 350, 95, 90, makecol(0, 0xff, 0xff)); |
6 | triangle(screen, 245, 21, 290, 350, 145, 90, makecol(0xff, 0xff, 0)); |
7 | rect(screen, 0, 0, 639, 479, makecol(0xff, 0xbf, 0x00)); |
8 | putpixel(screen, 0, 0, makecol(0xff, 0xff, 0xff)); |
9 | putpixel(screen, 639, 0, makecol(0xff, 0xff, 0xff)); |
10 | putpixel(screen, 0, 479, makecol(0xff, 0xff, 0xff)); |
11 | putpixel(screen, 639, 479, makecol(0xff, 0xff, 0xff)); |
12 | putpixel(screen, 0, 478, makecol(0xff, 0xff, 0xff)); |
13 | putpixel(screen, 639, 478, makecol(0xff, 0xff, 0xff)); |
14 | rectfill(screen, 16, 300, 256, 420, makecol(0xff, 0xff, 0xff)); |
15 | |
16 | textout_ex(screen, font, "Partially cut off text", -3, 450, |
17 | makecol(255,255,255), -1); |
18 | textout_ex(screen, font, "Hello World!", 70, 330, BLACK, -1); |
19 | textprintf_ex(screen, font, 70, 350, makecol(0, 0, 0), -1, |
20 | "FPS: %.2f", fps_rate); |
21 | |
22 | /* Now here's the interesting part. This section of code tests |
23 | * the various blit combinations supported by AllegroGL. That is: |
24 | * screen -> sub-bitmap of screen |
25 | * sub-bitmap of screen -> sub-bitmap of screen |
26 | * screen -> screen |
27 | * video bitmap -> screen |
28 | * screen -> memory bitmap |
29 | * memory bitmap -> screen |
30 | * rle sprite -> screen |
31 | * |
32 | * Other combinations are tested either at the init. |
33 | */ |
34 | |
35 | blit (screen, sub_screen, 256, 192, 0, 0, 128, 96); |
36 | blit (sub_screen, sub_screen2, 0, 0, 0, 0, 128, 96); |
37 | blit (screen, screen, 0, 0, 400, 150, 90, 90); |
38 | blit (vid_bitmap, screen, 0, 0, 0, 0, 50, 50); |
39 | blit (vid_bitmap2, screen, 0, 0, 50, 0, 50, 50); |
40 | blit (screen, mem_bitmap, 0, 0, 0, 0, 50, 50); |
41 | blit (mem_bitmap, screen, 0, 0, 100, 0, 50, 50); |
42 | |
43 | masked_blit (vid_bitmap, screen, 0, 0, 0, 50, 50, 50); |
44 | masked_blit (vid_bitmap2, screen, 0, 0, 50, 50, 50, 50); |
45 | masked_blit (mem_bitmap, screen, 0, 0, 100, 50, 50, 50); |
46 | |
47 | draw_sprite(screen, vid_bitmap, 0, 100); |
48 | draw_sprite(screen, vid_bitmap2, 50, 100); |
49 | draw_sprite(screen, mem_bitmap, 100, 100); |
50 | draw_rle_sprite(screen, rle_sprite, 150, 100); |
51 | |
52 | set_alpha_blender(); |
53 | draw_trans_sprite(screen, trans_vid_bitmap, 0, 150); |
54 | draw_trans_sprite(screen, trans_vid_bitmap2, 50, 150); |
55 | draw_trans_sprite(screen, trans_mem_bitmap, 100, 150); |
56 | draw_trans_rle_sprite(screen, trans_rle_sprite, 150, 150); |
57 | |
58 | pivot_scaled_sprite(screen, vid_bitmap, 0, 200, 0, 0, itofix(6), ftofix(1.1)); |
59 | pivot_scaled_sprite(screen, vid_bitmap2, 50, 200, 0, 0, itofix(6), ftofix(1.1)); |
60 | pivot_scaled_sprite(screen, mem_bitmap, 100, 200, 0, 0, itofix(6), ftofix(1.1)); |
61 | |
62 | /* Write the captions for each image */ |
63 | textout_ex(screen, font, "blit", 200, 25, CYAN, BLACK); |
64 | textout_ex(screen, font, "masked_blit", 200, 75, CYAN, BLACK); |
65 | textout_ex(screen, font, "draw_sprite", 200, 125, CYAN, BLACK); |
66 | textout_ex(screen, font, "draw_trans_sprite", 200, 175, CYAN, BLACK); |
67 | textout_ex(screen, font, "pivot_scaled_sprite", 200, 225, CYAN, BLACK); |
68 | textout_centre_ex(screen, font, "vid", 25, 275, CYAN, BLACK); |
69 | textout_centre_ex(screen, font, "NPOT", 25, 285, CYAN, BLACK); |
70 | textout_centre_ex(screen, font, "vid", 75, 275, CYAN, BLACK); |
71 | textout_centre_ex(screen, font, "POT", 75, 275, CYAN, BLACK); |
72 | textout_centre_ex(screen, font, "mem",125, 275, CYAN, BLACK); |
73 | textout_centre_ex(screen, font, "rle",175, 275, CYAN, BLACK); |
74 | |
75 | drawing_mode(DRAW_MODE_SOLID, 0, 0, 0); |
76 | rectfill(screen, 350, 400, 400, 450, CYAN); |
77 | drawing_mode(DRAW_MODE_XOR, NULL, 0, 0); |
78 | rect(screen, 370, 420, 380, 430, CYAN); |
79 | drawing_mode(DRAW_MODE_SOLID, 0, 0, 0); |
80 | |
81 | polygon(screen, 6, poly_coords, CYAN); |
82 | drawing_mode(DRAW_MODE_TRANS, 0, 0, 0); |
83 | set_trans_blender(305, 255, 305, 128); |
84 | rectfill(screen, 270, 400, 300, 450, BLACK); |
85 | drawing_mode(DRAW_MODE_SOLID, 0, 0, 0); |
86 | |
87 | /* video -> screen stertching */ |
88 | stretch_blit(large_vid_bitmap, screen, 0, 0, large_vid_bitmap->w, large_vid_bitmap->h, |
89 | 460, 350, large_vid_bitmap->w+50, large_vid_bitmap->h); |
90 | |
91 | allegro_gl_unset_allegro_mode(); |
All you need is allegro_gl_set/unset_allegro_mode();
Switching to AllegroGL however would require learning OpenGL, which is more complicated, and is a bit much for 2d games.
You're not really required to learn any OpenGL, as Gull stated; and if you do, you'll find it's not really hard. It's also very suitable for 2D applications: You just need to set up a proper ortho projection and make a wrapper to draw a sprite, which is pretty much this:
render_sprite(GLuint texhandle) { glBindTexture(GL_TEXTURE_2D, texhandle); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoords2f(0, 0); glVertex2f(0, 0); glTexCoords2f(1, 0); glVertex2f(1, 0); glTexCoords2f(1, 1); glVertex2f(1, 1); glTexCoords2f(0, 1); glVertex2f(0, 1); glEnd(); }
...which renders a sprite at (0, 0), sized 1x1. You can use all sorts of matrix transformations (less frightening than it sounds) to put the sprite wherever you want.
To the OP:
Allegro SDL Alle SD is faster!!!11
Seriously: the two libraries have different purposes. Allegro is a game library with loads of useful functions (especially for retro-games).
SDL is a hardware abstraction library. It just gives you cross-platform low-level access to the hardware and that's it. SDL doesn't even have a software mixer or drawing primitives. All you can do is putting out ONE stream of audio and accessing the frame buffer. And about the extension libraries, like SDL_image, SDL_mixer and SDL_ttf -- they are crap.
Why not benchmark OpenLayer together with Allegro and SDL
Why not benchmark OpenLayer together with Allegro and SDL?
Because the results would blow our minds and break the universe;)
I was thinking of switching over to SDL a couple years ago, but then I decided against because I was/am lazy that way.
The main difference I can see between your two code snippets is that the SDL has an explicit SDL_UpdateRects, which is a call that Allegro has no analogue to. In SDL terms, it says "I've changed this part of the display, please ensure my change was processed" - which is extremely handy when your program only outputs in one colour depth/format and SDL is displaying your output on a screen with a different colour depth/format because it severely cuts down the amount of work that has to be done. Partly because you don't necessarily want the entire screen to be updated, but mostly because it gives you a chance to explicitly say "the drawing is done now, update the real display if you need to".
That said, you've mangled the call to SDL_UpdateRect (why change it from (target, x, y, x+garbage->w, y+garbage->h) to (target, x, x, y+garbage->w, y+garbage->h)?) so if the demo is still appearing correctly then it seems there is no colour conversion required and the call has no effect in this particular program versus your particular display.
But overall, I agree with everyone else. Use a proper hardware API like OpenGL if you actually care at all about performance. And for god's sake, please remember not to use 100% CPU if you don't need to. And rest(1) is not sufficient!
Allegro is not made for cutting-edge performance, but rather for solid multiplatform programming with a relatively easy-to-use interface with decent performance
This is something of a reimagining, isn't it? Allegro is made for cutting-edge 1994 performance and retains lots of exciting ASM optimisations for 486 processors. It has a complicated API that's designed for the world of MS-DOS, though it has some extensions that can, sometimes, provide decent performance on Windows computers. Software rendering performs reasonably well on Windows versions prior to Vista, on all other operating systems it is extremely slow.
It doesn't matter how you get there, and I'm repeating myself and everyone above me, but I can't see that it makes any sense to plan anything other than an OpenGL route nowadays.
Even Allegro's 'poor' 445385 blits per second would let you have 9000 sprites on the screen running at 50fps. Is that not enough?
I'm not an SDL expert but, in your SDL benchmark, you're not initialising Pos. So Pos.x and .y might well be offscreen, which means that SDL_BlitSurface will return very quickly without doing anything. Likewise SDL_UpdateRect - I guess that will also do nothing if if y+garbage->w <= x. Thomas can probably comment.
Last time I checked, Allegro's exciting asm code did make it faster than SDL in some circumstances (memory blits with colour conversion IIRC) but I think modern compilers have made Allegro's C version as good as the asm, so that probably no longer applies.
Allegro's good because it includes a lot (SDL doesn't even have putpixel) but bad because it's hard to make proper use of modern hardware. The API choice is more a matter of personal preference. IMO.
Pete
Well, I've recently switched from Allegro to SDL, and I'm quite happy with the switch. However, I did it precisely because I needed less and less of Allegro, until all that was left could easily be provided by SDL (or either SDL_image, SDL_mixer, SDL_ttf).
In my opinion SDL allows for cleaner code when used only as a basis for and engine and (whether we like it or not) it has a bigger user base and wider cross-platform capabilities, which is always nice.
On the other hand, Allegro is way better for people who are still learning exactly because of its all-in-one approach, and newbies are likely to be satisfied by what Allegro offers out of the box. However, when you start needing more, you are forced to use a lot of add-ons (AllegroGL for graphics, AlOgg for music, something for PNGs and JPGs, something for TTF fonts etc.) and this advantage is lost, as you can just as easily find similar add-ons built on top of SDL.
break the universe
I see an openning for a Douglas Adams quote!
There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened.
I see an openning for a Douglas Adams quote!
There is a theory which states that if ever anybody discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened.
I wasn't thinking of the Hitch Hiker's Guide to the Galaxy, but props to you! It's all good!
... I mean, yes. Congratulations on picking up on my (thinly) veiled reference to a great work of art
I'm not an SDL expert but, in your SDL benchmark, you're not initialising Pos. So Pos.x and .y might well be offscreen, which means that SDL_BlitSurface will return very quickly without doing anything. Likewise SDL_UpdateRect - I guess that will also do nothing if if y+garbage->w <= x. Thomas can probably comment.
It's my own fault for misreading the documentation, writing the original comparison incorrectly and posting incorrectly on this thread, but arguments to UpdateRect are (x, y, width, height). So whether y+garbage->w should always do at least as much as you want depends on whether y is always positive. Since it seems not to be set, I guess it's hard to be sure!
Allegro's good because it includes a lot (SDL doesn't even have putpixel) but bad because it's hard to make proper use of modern hardware. The API choice is more a matter of personal preference. IMO.
To further this comment, SDL was designed as a hardware API abstraction layer. It's pretty much a subset of DirectDraw with a much nicer API. It's a conduit to blitter hardware. If you want anything more than that then it also encapsulates OpenGL.
Allegro is an "everything you could ever want" library from the DOS era. So it has a million different functions, and a million ways of doing any single thing. It is extremely difficult to adapt to any hardware API in particular and no longer provides anything like "everything you could ever want" as people have stopped storing their graphics in PCX files, using bitmapped fonts and playing their music from MIDIs.
I think Peter has a good point re:9000 sprites at 50 fps. Though I would prefer a CPU + GPU solution (e.g. SDL in OpenGL mode, AllegroGL, OpenLayer) because it distributes the processing across the computer and thus distributes the heat, meaning that fans are less likely to come on. That is, provided you don't do some 80s style busy waiting!
I'm tempted to switch to SDL too, I use OpenGL for graphics and allegro for everything else (except GUI and 3D), I have a few questions for those who already use SDL:
- what compilers it supports ?
- does it use OpenGL natively or it has an add-on ?
- for what Jakub said, are those add-ons (PNG, OGG, TTF) easier/better than allegro's ?
- does it have a GUI API ?
- does it have a datafile/resource API ?
- for Mac OS, is it easier/better supported than allegro ?
- and same question for networking..
what compilers it supports
Much the same as Allegro, with some more diverse 'unsupported' targets (Dreamcast, Symbian, etc)
does it use OpenGL natively or it has an add-on
Natively, but all it will help you do graphics wise is create the OpenGL window (or full screen mode, obviously) — it's not going to open PNG files and repackage them into GL textures on its own, for example. Which OpenLayer will.
for what Jakub said, are those add-ons (PNG, OGG, TTF) easier/better than allegro's ?
They're probably much the same. There's no 'PNG' or 'OGG' add-ons in that sense though. SDL_image handles loading image files (other than BMP, which is built into the base library) — which includes PNG. And JPEG. And a bunch of others. Similarly SDL_mixer provides a bunch of helpful stuff for sound and music files.
does it have a GUI API
No.
does it have a datafile/resource API
No.
for Mac OS, is it easier/better supported than allegro
It's better supported. The API is the same on OS X as the other platforms, so I guess the answer to the rest of the question depends on your perspective on that.
It has a built in thread-safe message passing system which in my opinion makes it easier to combine SDL programs with native GUIs than Allegro, if you're talking about putting a cocoa front-end on a program or something like that.
and same question for networking
There's no networking built into SDL, much as there isn't any networking built into Allegro.
[...] SDL was designed as a hardware API abstraction layer. It's pretty much a subset of DirectDraw with a much nicer API. It's a conduit to blitter hardware.
SDL also provides low-level interfaces to most other hardware a game would need - keyboard/mouse/joystick input, audio and video output. It also includes threading (something that I consider a big gap in Allegro's API) and timing.
I think Peter has a good point re:9000 sprites at 50 fps.
Yup, it's great while you think simple - but let us remember that these are raw blit()'s, no masking, no blending, no transformations. The practical number is likely to be lower, and once you start talking about 100FPS (my refresh rate while I was still using a CRT) it does become annoying. Likewise when you would like to run in 1680x1050 (my LCD's native resolution) with double-buffering.
- does it have a GUI API ?
- does it have a datafile/resource API ?
- and same question for networking.
Nope, but that is its advantage for me - it's smaller and cleaner because of this, and allows you to mix and match until you're happy. That was the main reason I started considering SDL instead of Allegro - I realised that aside for initialization, I use about 10 functions total from Allegro since I replaced almost everything for one reason or another . And most of those functions left were hidden under a wrapper of sort, which made it easier to replace them.
for what Jakub said, are those add-ons (PNG, OGG, TTF) easier/better than allegro's
While they are not easier or better per se, they are much more stable on average. Don't get me wrong, I'm very impressed with the consistent updates of some of Allegro add-ons (for example, lillo was always doing a great job on JPGAlleg), but some are notorious for being buggy and/or out of date. I can think of about five different TTF libs for Allegro, most of which either are no longer compatible with newer versions of Allegro, have weird installation issues with newer compilers, or are just plain buggy. SDL_ttf on the other hand is (as far as I can tell) well-maintained and up to date.
what compilers it supports
As Thomas said, there is a large array of unofficial ports, which are less frequently updated - but you can usually find a stable if a bit dated version for most hardware. Still, both are portable enough across the popular platforms, with SDL probably having a bit of an edge on Macs. Also, there are some notable advantages in Windows joystick handling (Allegro sometimes reports incorrect/incomplete stick data).
This enlightened my mind. Thank you and bye.
I must do this now that my program's development is frozen due to lack of inspiration.
thanks for the replies guys, I think I must try it.
in my case, the only downside I see now, is the lack of a datafile and packfiles, but I guess that can be implemented without much trouble or perhaps rip it off from allegro.
Re: my example is flawed responses.
Well, I don't know any SDL, I just copied the code I link to, and then messed with it a bit to find out why it was crashing, so I have no idea if it is a fair or unfair benchmark. Which is also why I posted this thread in the first place.
Re: 9000 sprites at 50 fps
Those are 32x32 sprites. If there's 0 overlap there are 1280 of those onscreen at a time. I agree this should definitely be enough, however the problems start when you add logic into it, because the drawing+logic take a serious toll on the CPU, which is why having "lighter" drawing is nicer.
I was particularily crossed by the "Tiny new physicsy game" I posted a while back. When I ran that on 1280x1024 with memory bitmaps it ran like crap, even though its only a black background and a couple of lines and filled circles (oh, and some text), I admit there's no clever dirty rectangles or any other performance boosters, but its a fact that my CPU was unable to run that game properly. (It actually ran perfectly fine when I switched to video bitmaps [which I forgot about ], but I understand those don't work perfectly yet [or even worse than memory bitmaps in some/most? cases])
Re: Not use 100% CPU
That was just a test to see how it performed under pressure. Obviously I don't use 100% CPU for games most of the time.
IMO SDL is nice, but when you use it, consider doing the gfx with OpenGL.
What I don't like are the "addon" libraries like SDL_mixer, SDL_image or SDL_ttf. They are bloated and not implemented very well. I mean, in a game where I only need to open PNG files, SDL_image forces me to include a whole JPEG library. In a game where I write my own music engine SDL_mixer forces me to include MP3 (libmad), OGG (libvorbis), MOD (mikmod ) and MIDI (timidity) libraries. And SDL_ttf is just a thin wrapper around the freetype library, no need for an extra DLL.
Okay, I'm wondering what else needs to be done to prevent a 100% CPU usage outside of using rest(1).
Simon Parzer: You can always grab that code, reuse it and put it as part of your application, as I did with AlOgg and loadpng for Allegro in mine. That way, you can pick which features you like/need from the original libraries. Unless, of course, they are maintained on a monthly or more frequent basis, which seems not to be the case anymore.
Well, actually, both SDL_image and SDL_mixer allow you to choose the formats you want to support when compiling, and IIRC they even handle this automatically. That is if you don't have a dependency needed for a given format, support for it is dropped during ./configure.
I compiled my SDL_mixer to only support OGGs.
But hey, I'm not claiming SDL or its addons don't have any flaws. I'm just liking it more so far, that's all.
Okay, I'm wondering what else needs to be done to prevent a 100% CPU usage outside of using rest(1).
me too.
I think that it should also be mentioned that Allegro is essentially public domain while SDL is LGPL. I've also considered many times using SDL, simply because I prefer using OpenGL, anyway, and don't need the vast majority of Allegro's functions... I just haven't managed to take that step yet.
[EDIT] Besides, Allegro has the Speedhack... that alone should be worth it, right?
Whats wrong with the LGPL? You dont have to include the license if your program is closed source. You can sell your program. LGPL FTW!
P.S. Still, no license is better than any license
P.S. Still, no license is better than any license
No licence means its 100% proprietary, and no one is technically aloud to use, or distribute it.
A licence is just an "easy" way of giving broad permission to "people" to use and/or distribute your work.
I'm now using PTK instead of Allegro, and even though it's a bit buggy and I'm not that fond of the API, it gives me all the basics needed and hardware acceleration (via OpenGL or DirectD3D).
I'm about to run for a train, so no time to post at length. Apologies for that, keep in mind that I'm not being deliberately short.
Re: Not use 100% CPU
That was just a test to see how it performed under pressure. Obviously I don't use 100% CPU for games most of the time.
Oh, I didn't mean the example specifically. It's clearly meant to be a stress test, so 100% CPU is appropriate.
SDL_image forces me to include a whole JPEG library.
No it doesn't. It can load the LibJPEG (or whatever its called) DLL at runtime, and simply not load JPEGs if the DLL isn't present.
Okay, I'm wondering what else needs to be done to prevent a 100% CPU usage outside of using rest(1).
Implementations vary, but the basic idea is that you either (a) use a vsync that sleeps properly (Allegro's may work, it's written in such a way that it may also silently fail); or (b) apply some simple timing logic.
You know how many FPS your game is supposed to work at. So you can work out how long each frame should take. You can also use timing to work out how long each frame has taken. And you can use rest to sleep for the number of milliseconds you specify. So you don't need to use 100% CPU.
We discussed this quite loudly recently, and opinions clearly vary, but for 'pure Allegro' (i.e. no extra libraries), I like this:
1 | unsigned my_timer_var; |
2 | my_timer_func() {my_timer_var++;} |
3 | |
4 | ... |
5 | int FPS_I_WANT = <whatever>; |
6 | |
7 | install_timer_bps(my_timer_func, FPS_I_WANT * 4); |
8 | ... |
9 | |
10 | ... |
11 | unsigned framestart = my_timer_var = 0; |
12 | |
13 | while(in_game_loop) |
14 | { |
15 | process_logic(); |
16 | draw_frame(); |
17 | |
18 | unsigned time_taken = my_timer_var - framestart; |
19 | if(framestart < 4) |
20 | { |
21 | rest( ((4 - framestart) * 250) / FPS_I_WANT); // converts from units of FPS_I_WANT*4 per second to 1000ths per second, i.e. milliseconds |
22 | framestart += 4; |
23 | } |
24 | else |
25 | { |
26 | if(framestart < 8) |
27 | { |
28 | skip next frame; |
29 | framestart += 4; |
30 | } |
31 | else |
32 | { |
33 | we're too slow, just jump up to date |
34 | skip next frame; |
35 | framestart = my_timer_var; |
36 | } |
37 | } |
38 | } |
Apologies, the above is just typed from the top of my mind, it isn't thoroughly checked.
I haven't read every message and don't know SDL, but surely SDL is using video and the allegro code is using memory buffers, which means the tests aren't equal in any way. Change the create_bitmap to create_video_bitmap and try it again.
but surely SDL is using video and the allegro code is using memory buffers
I don't think so — "SDL_CreateRGBSurface(SDL_SWSURFACE...)" means create a surface for the fastest possible software blitting, which on a PC means the same as creating a memory bitmap in Allegro. The DisplayFormat thing just makes sure that all the bytes/depths/etc are the same as the display buffer. So it creates a new surface, does a colour conversion blit to it from your original, and returns it.
EDIT: I spotted a logical error in the not-100% CPU code I posted above. You should probably change this bit:
else { we're too slow, just jump up to date skip next frame; framestart = my_timer_var; }
To something like:
else { we're too slow, just jump up to date skipped_count++; if(skipped_count&7) skip next frame; framestart = my_timer_var; }
So that if the computer in question just is too slow to play your game, you still display something, allowing the user to realise what is going on. In this case you'll display every 8th frame, still going too slowly.
Allegro is good for: one-hour hacking, simple testing, games, learning(?); you can scrape something together fairly fast from scratch or mod a previous project without too much thinking about hardware-level.
SDL is good for: providing an engine layer for a semi-serious (gamedev?) project. What you basically do when using SDL is to re-code Allegro as far as you need it. Of course it's faster etc., and combined with OpenGL also more powerful; nothing stops you from actually achiving commercial outlook with some labour (scenegraphs etc are available, OI e.g.). Now once you have a basecode set up, engine ready, SDL is as easy as you make it; possibly easier than Allegro.
Allegro is a general-purpose gamedev lib for simple apps and has primarily hacking interest to me (although there are impressive Allegro projects as well, of course).
Oh no! EVERYBODY'S LEAVING! COME BACK! COME BACK TO UNCLE ALLEGRO!
When I switched to SDL the graphics got way better, I finished all of my games, and millions of people started playing them.
When I switched to SDL the graphics got way better, I finished all of my games, and millions of people started playing them.
If you like SDL, you should try programming in HTML.
Naw, Matthew doesn't like to use variables..
means create a surface for the fastest possible software blitting
In that case, he should use create_system_bitmap
When I switched to SDL the graphics got way better
Is this why www.sdl.cc redirects to allegro.cc, is there something you haven't told us Matthew
Is this why www.sdl.cc redirects to allegro.cc, is there something you haven't told us Matthew
Incredibly it is the case ! I'm dumb! ! ! !
For all those SDL's addict: don't they have a forum for SDL related things ? Didn't you noticed that there is the word 'allegro' in each page of allegro.cc website ?
PS: The last comment is just pure jerk.
There is no such thing as an SDL community. There is only a mailing list for technical problems related to SDL.
So, just for that, SDL sucks.
A project without a community is / not fun / boring / pure shit .
A project without a community is / not fun / boring /
productive