sparrow3D - multi platform game engine


I installed the sdl projects necessary to build sparrow but I get some errors when trying to compile all targets:

./ undefined reference to `FT_Outline_Transform'

./ undefined reference to `FT_Load_Glyph'

./ undefined reference to `FT_Get_Kerning'

./ undefined reference to `FT_Set_Pixel_Sizes'

./ undefined reference to `FT_Stroker_Done'

./ undefined reference to `FT_Open_Face'

./ undefined reference to `FT_Done_Face'

./ undefined reference to `FT_Done_FreeType'

./ undefined reference to `FT_Init_FreeType'

./ undefined reference to `FT_Set_Charmap'

./ undefined reference to `FT_Stroker_Set'

./ undefined reference to `FT_Done_Glyph'

./ undefined reference to `FT_Glyph_To_Bitmap'

./ undefined reference to `FT_Stroker_New'

./ undefined reference to `FT_Get_Glyph'

./ undefined reference to `FT_Get_Char_Index'

./ undefined reference to `FT_Render_Glyph'

./ undefined reference to `FT_Set_Char_Size'

./ undefined reference to `FT_Glyph_Stroke'

SDL_ttf is installed and im using linux x86
Last edited by a moderator:

gcc -march=native -DX86CPU -g -ffast-math  -O2 -fsingle-precision-constant -fPIC testsparrow.c `sdl-config --cflags`   -I.  -L.  -lSDL_mixer -lSDL_ttf -lSDL_image -lSDL -lm -lsparrow3d -o ./testsparrow
Last edited by a moderator:
Put "-lsparrow3d" before "-lSDL_mixer", gcc checks libraries from right to left as i know.

I moved the includes around in the makefile and now the compiler does this

gcc -march=native -DX86CPU -g -ffast-math  -O2 -fsingle-precision-constant -fPIC testsparrow.c     -lsparrow3d -I. -L. `sdl-config --cflags` -lSDL_mixer -lSDL_ttf -lSDL_image -lSDL -lm        -o ./testsparrow
Maybe you have to give the freetype library to the linker on your own with -lfreetype?

Did you use SDL-ttf2.0 (and not SDL-ttf1.0 if this even exist)?
Maybe you have to give the freetype library to the linker on your own with -lfreetype?

Did you use SDL-ttf2.0 (and not SDL-ttf1.0 if this even exist)?
yep, using -lfreetype in the makefile worked thanks,

also I had rename the downloaded folder from sparrow3d-master

to sparrow3d

then I had to copy all the .so files into /usr/lib

now I have a nice spinning textured cube on screen :D

BTW how do I compile for handhelds?

and if you translated this engine into Monkey it could run on a html5 canvas,flash,android,iphone
Last edited by a moderator:

I got it compiled for pandora thanks
Last edited by a moderator:
Hey guys,

I did a few things.

First of all, I rewrote the example application. It spent too much time to compile and was not modular enough... Now every example case is an own file and I can easily add new examples and don't have to recompile everything. :) Oh, make -j works now, too. ;)

Furthermore I started to implement a structure called "blocked Text". It is useful e.g. for scrolling text. You will see it in the video (last test case).

I also improved sparrowNet a lot. In fact I started to implement it at all. ^^ At the moment TCP sending and receiving works. Furthermore sparrowNet is able to search and read your c4a-prof file, read your (or all) scores from skeezix server and to commit scores, if they didn't exist for you yet - without the need of spaghetti client! So in fact I can do this on every supported target. I will show this feature soon™ in a new version of puzzletube.

But for now: A new video of the test application (oh, did I mention the new font?)

greetings, Ziz
Oooh, liking the new effects. Think I'll probably try and pick up Sparrow on my next project.

Are you going to support UDP in sparrowNet?
Are you going to support UDP in sparrowNet?
Maybe... Probably, when I need it. ^^ For now I thought, that TCP should be enough for games. UDP in games (except video or audio stream) can be quite complex. However, of course, it is faster... I will have a look. :) I should implement some broadcasting stuff, too. ;)
For all, who may interested:

After finishing Snowman it was time for me to improve sparrow3d a bit again, so today I implemented sparrowMapping, a new attempt for button mappings.

I already had some attempts to abstract the very different button labeling via two approaches

  • Calling them by their position. SP_BUTTON_LEFT e.g. is (A) on the pandora, but (X) on the GCW. That is quite useful, when the button positions is important like for Puzzletube
  • Calling them by simple functions. So I defined SP_PRACTICE_OKAY and SP_PRACTICE_CANEL, which is mapped to the mostly used button for "okay" and "cancel". However as you all may know: There isn't a real defacto standard for "okay" and "cancel" on the pandora, so that doesn't help much.
So I did a new attempt and put it into an own part. The idea is too define two things
  • semantic buttons, which may have names like "fire button" or "jump button" with no fixed mapping to a real button of the device.
  • a button pool, which can be used to map these semantic buttons to real buttons
What does this look like?In the past I had things like this:

if (spGetInput()->button[SP_LEFT_BUTTON])
spGetInput()->button[SP_LEFT_BUTTON] = 0;
//do something fancy!
Now I first define my semantic buttons with an (unique) ID and a name
I put (A),( B) ,(X),(Y),(L) and ® to the pool, so that the user can later select one of these button for mappings. As you may see, I don't want the user to be able to choose Select or Start, so I didn't put it to the pool.Afterwards I created the semantic buttons with preset mappings. spMapButtonAdd has four arguments. First an unique ID, which could be defined via #define first to be easier to remind. Then an internal name, which can be used for referencing the button, too. However this is slower. In fact this name shall be used later for automatically saving and loading the mappings. Then the caption of the semantic button follows. This is, what the user shall read, so "Fire" or "Fire button" makes sense. At last the preset mapping.

How to use it? As said, there are two ways. Via ID (fast) and via name (slower):

#define FIRE_BUTTON 0
if (spMapGetByID(FIRE_BUTTON))
//do something fancy!
if (spMapGetByName("fire"))
   //do something fancy!
So the mapping is now pure semantic!
However, there are disadvantages now. In the past I could do this:

drawText("Press "SP_BUTTON_START_NAME" to exit.");
The button name isn't a #define anymore, so I have to concatenate the strings on my own:
char buffer[256];
sprintf(buffer,"Press %s to exit.",spMapCaptionByID(EXIT_BUTTON));
But you can see, I could change the exit button mapping now much easier. ;)
My next goal is to add some config writing and reading possibilities to sparrowFile. Afterwards I will use this to save and load the mappings and maybe add them in Snowman, too, as many people seem to be too confused to jump with (Y). ;)



PS: Documentation is up2date, too:
Does this break all the current input handling? or is it just a new layer?

I'm also not sure I really get what your change trying to achieve
No, it doesn't break anything.

As you said it is a new layer to handle button mappings in an easy way and without the need to implement it in every application again.

As said the new approach is function/semantic based and not name or location based anymore. I don't check, whether button A or the left button is pressed, but if the fire button is pressed - without the need to know, which button this is. :)

However if you don't see an usecase, you can totally ignore this new layer. ;)
@pmprog, It's basically one layer of abstraction. Now you don't have to hard-code buttons for each device any more and furthermore building a system to give the user the option to change the mapping during runtime should be MUCH easier.

Generally speaking it gives you a lot more options to handle input.
Last edited by a moderator:
I think, it didn't come out, why you first have to create a pool:

I also added function to make it easy to change the button mapping. If the users wants to change a mapping, you have to call spMapStartChangeByID(FIRE_BUTTON); or spMapStartChangeByName("fire");. That initiates the process of change. Afterwards you have to call spMapContinueChange(); in the calc function, so that sparrowMapping can check, whether the user entered a new mapping for the button and whether this mapping is part of the pool. With this I can prevent, that the users chooses a button I don't want him to choose like Start or Select or maybe the shoulder buttons.

While changing a button 4 strategies can be used.

  • SP_MAPPING_NONE: the new mapping will be set without checking, whether it is already choosen
  • SP_MAPPING_SWITCH: If a conflict appears, the mappings will be switched. E.g. if you have mapped (A) to FIRE_BUTTON, (X) to JUMP_BUTTON and want to change the mapping of FIRE_BUTTON to (X), the mapping of JUMP_BUTTON will be set to (A).
  • SP_MAPPING_OTHER_INVALID: Removes the mapping of a button at conflict. E.g. if you have mapped (A) to FIRE_BUTTON, (X) to JUMP_BUTTON and want to change the mapping of FIRE_BUTTON to (X), the mapping of JUMP_BUTTON will be set to -1. You can check for this button, but because of the missing mapping, it will never be pressed. However the user will read "None" for the mapping and can change this to a free button, later. ;)
  • SP_MAPPING_CANCEL: If the button is already mapped, nothing happens, but spMapContinueChange(); returns 2, so you can write a hint for the user like "Button already used, use another!"
Furthermore I added the functionality to save and load these mappings. Have a look at test_mappings.c to see, how it is done in detail, but in fact you just have to call spMapLoad("testsparrow","controls.cfg"); after you setup the pool and the default mapping and spMapSave("testsparrow","controls.cfg"); everytime you want to save the mapping. :)
Oh and I also added some functions to save/load easy configs with the format

key: value
So this may be handy, too. ;) Just have a look at the documenation.

Last edited by a moderator:
I really should spend some time and learn how your in-built input system works
Today I implemented, that you can type "{buttonname}" in spFont and it will resolve it to the real button behind this buttonname!

For an example have a look at the snowman help code:

		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*6,-1,"{shot}: Shot (costs 2 snow) {triple}: 3 shoots",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*5,-1,"{jump}: Jump (costs 1 snow)",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*4,-1,"{broom}: Broom Bash - 2x damage with a broom!",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*3,-1,"{ball}: Ball Attack (costs your big belly)",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*2,-1,"{help}: (Un)show mini help",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)-font->maxheight*1,-1,"[R]: Pause and options",font);
		spFontDrawMiddle(screen->w>>1,(screen->h>>1)+font->maxheight*0,-1,"[B]: Exit",font);
Ingame instead of {shot} the button used for shooting will be shown. ;)