Hi people,
First of all i write on the BomberClone game and i have run into
some difficults to do the playeranimations. I don’t really care how
much they need on the harddrive but i do care about the memory
usage if the game is running… and it’s getting to high for me…
have anyone a good idea of how to load the gfx very fast and to put
it on the screen.
Forget that, unless you’re building arcade machines or working on
consoles. You can’t rely on real time streaming on a normal computer.
Or how to do save some memory ?
Well, first of all, how much memory are you using? I mean, this was a
problem back in the C64 and Amiga days, where memory size was
practically fixed (64 and 512 kB respectively), and expansions were
insanely expensive and/or not straightforward for games to use.
Nowadays, we’re closer to talking about hundreds of MB than hundreds
of kB. Even an old machine with, say 32 MB, can hold lots of
graphics. 16 MB is thirteen 640x480x32 images. That’s 3900 32x32
sprites or tiles. Who the h*ll is going to draw all that!?
[…]
if i start a game i do the following things:
- load the player gfx
- scale it to the right resolution
- load the tileset
- scale it to the right resolution
- go into the game loop
- free the tileset gfx
- free the player gfx
That’s pretty much what I do in Kobo Deluxe too. There are various
options for dealing with filtering and edges, and some alpha cleaning
and other image processing “plugins”, but the net result is the same;
the game runs with all graphics scaled to the screen resolution and
SDL_DisplayFormat*()ed for performance. (This applies to glSDL mode
as well, except in 320x240, where glSDL steps in and scales to
640x480 in hardware.)
right now my scaling routine is quite slow… so if someone knows a
faster one please let me know…
Tell me if you find some code. My scaling code isn’t exactly lightning
fast either; especially not the hackish "bilinear with oversampling"
modes. (I’m just chaining a few instances of the scaling plugin.
It does do bilinear interpolation, though (and two more exotic styles
for 2x), and is at least written in reasonably “direct” C code for
the most part. Try it and see.
the gfx source you can look at
here: (i use this link because of the colors there they makes it
much easyer to read):
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/bomberclone/bombercl
one/src/gfx.c?rev=1.16&content-type=text/vnd.viewcvs-markup
the routines are : gfx_load_players and scale_image
Ah… Well, first of all, you should “warp” the loops a bit here.
putpixel() isn’t even inlined, and it contains a pixel format switch.
The function call and the switch() is what burns your cycles; not the
actual pixel shuffling code.
Do the who scaling operation in one function instead, or use inline
functions if it gets too hairy otherwise. Decide first what pixel
size to use (1-4 bytes), then have one function for each size. For
"nearest" scaling, you don’t have to mess with the individual fields,
so pixel size is all you need to know.
Second, my qualified guess is that the “pattern” arrays actually slow
things down. Getting the values from them is most probably more
expensive than just calculating them on the fly. This applies to
anything newer than a 386 CPU, I think. Just use fixed point
calculations instead. Simpler, faster and more flexible.
Note that you only have to optimize horizontal runs. The vertical loop
stuff is only executed once per pixel row, so unless you have tons of
tiny surfaces, don’t worry about it.
Here’s my “nearest” scaling inner loop and it’s inline functions:On Tuesday 03 June 2003 20.51, Steffen Pohle wrote:
static inline pix_t getpix32(SDL_Surface *s, int x, int y)
{
pix_t *p;
if(x < 0 || x >= s->w || y < 0 || y >= s->h)
return getpix32_empty;
p = (pix_t *)((char *)s->pixels + y * s->pitch);
return p[x];
}
static inline void setpix32(SDL_Surface *s, int x, int y, pix_t pix)
{
pix_t *p;
if(x < 0 || x >= s->w || y < 0 || y >= s->h)
return;
p = (pix_t *)((char *)s->pixels + y * s->pitch);
p[x] = pix;
}
for(y = start_y, sy = start_sy; y < nh; ++y, sy += scy)
for(x = 0, sx = start_sx; x < nw; ++x, sx += scx)
setpix32(tmp, x, y, getpix32(s->surface,
sx >> 16, sy >> 16));
Have a look in graphics/sprite.c for the full code.
Note that the plugins deal only with 32 bit RGBA surfaces.
Interpolation, alpha effects and some other stuff require messing
with the individual fields, and I couldn’t be arsed to make three
versions of everything. SDL’s conversion routines are pretty damn
fast, fortunately.
Also note that the clipping is only needed around the edges, and not
at all in “nearest” mode, so there’s quite some room for optimization
here. (This is “first try” code; not much planning and no
optimization.) Conditionals are expensive, and I suspect there are
enough of them here to freak out the prediction on most CPUs. I’ll
deal with it some time… Maybe.
//David Olofson - Programmer, Composer, Open Source Advocate
.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`-----------------------------------> http://audiality.org -’
— http://olofson.net — http://www.reologica.se —