GP2X Compiling For The Gp2x On Linux?


reiboul

Peace sells... but who's buying?
Joined
Jul 16, 2006
Messages
587
Age
37
Location
France
Website
Visit site
Hi everyone!
I'm getting started with SDL and wrote a (very) little game that I want to compile for the GP2X
Unfortunately I haven't found a simple solution and everywhere I search I found something else :(

I'm running Ubuntu Edgy and wondered how I can compile a small C++/SDL app (using only iostream, SDL.h and ctime

Is there any way of using GCC to build ARM programs? or is there an easy tutorial around here?

Many thanks ;)
 
For me it was as easy as checking it out from the svn, then typing make, then make install (as root of course). Others have had problems, I don't know why.
 
I think I finally have the toolchain installed... But i think I had errors, so i'm 'making' the toolchain again :(

Anyway, when I tried to compile I had errors :

/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: skipping incompatible /usr/lib/libSDL.so when searching for -lSDL
/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: skipping incompatible /usr/lib/libSDL.a when searching for -lSDL
/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: cannot find -lSDL
collect2: ld returned 1 exit status


What should I do? i'm using
open2x-gcc Main.cpp `sdl-config --cflags --libs` -Wall
to compile...
How can I include SDL? is #include"SDL.h" ok? (i saw this on an example) what options should I use? sorry but i'm noobish at SDL :(

(the programs compiles and run fine using GCC on my computer)
 
/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: skipping incompatible /usr/lib/libSDL.so when searching for -lSDL
/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: skipping incompatible /usr/lib/libSDL.a when searching for -lSDL
/lib/gcc/open2x/4.0.2/../../../../open2x/bin/ld: cannot find -lSDL
collect2: ld returned 1 exit status

What should I do? i'm using
open2x-gcc Main.cpp `sdl-config --cflags --libs` -Wall

You should use $(PATH_TO_OPEN2X)/bin/sdl-config instead of your default system. You are trying to link x86 libraries against arm objects which is why you are getting errors.

Try -static as well because, if it works, it will remove any library requirements from the gp2x. I haven't had much luck with that but maybe you will.

Cheers,
Charlie
 
Last edited by a moderator:
Alternatively you may avoid sdl-config. Using -L(path to open2x/libs dir) and -lSDL isn't the best way, but it does the job.
For my stratagus build, -static was the only way to get it working. Otherwise, my build would get link errors at runtime (But before i used LD_LIBRARY_PATH... Heh.)

If your interested in getting an IDE, Code::Blocks is the way to go. Nightly builds here:http://forums.codeblocks.org/index.php?topic=4867.0

CVS is off, for some reason, so your chained to Ubuntu 6.6 and SuSE 10.0 + (Not sure if this is what edgy is, so I'm not sure if you use it.).

Works on SuSE 10.2 for me. Maybe it will work for you too.
 
I don't mind whether I use Open2x or Code::block, all i want to do is to compil my .cpp files, just as if I were using gpp to compil a linux-exe :(

I successfully created a test program.gpe with Open2x, but it's segfaulting my GP2X :( It works fine on my computer, same code
I'm using SDL_SWSURFACE, 16bpp, what else should I do??

Thanks for all your help ;) i'm about to compile my first GP2X program!

[root@gp2x sd]$./test.gpe
SDL_GP2X: CreateDevice
SDL_GP2X: VideoInit
SDL_GP2X: Physical screen = 320x240 (ilace = 0, pol = 0)
SDL_GP2X: InitHWSurfaces
SDL_GP2X: InitHWSurfaces scratch = 0
SDL_GP2X: Creating cursor 16x16
SDL_GP2X: Allocated WMcursor @ 0x18ce68 (32)
SDL_GP2X: SurfaceManager allocating 256 bytes
SDL_GP2X: SurfaceManager adding new free bucket of 5242624 bytes @ 0x18ce80
SDL_GP2X: SurfaceManager allocated 256 bytes at 0x41100000
SDL_GP2X: Looking for a mouse
SDL_GP2X: No mice found
SDL_SYS_JoystickInit
SDL_GP2X: SYS_JoystickName(0)
SDL_GP2X: ListModes
SDL_GP2X: Setting video mode 320x240 16 bpp, flags=40000001
SDL_GP2X: Freeing cursor 0x18ce68
SDL_GP2X: SurfaceManager freeing 256 bytes @ 0x41100000 from bucket 0x18c5d8
SDL_GP2X: merging with next bucket (0x18ce80) making 5242880 bytes
SDL_GP2X: FreeHWSurfaces
SDL_GP2X: Freeing bucket 0x18c5c0 (size 17825792)
SDL_GP2X: Freeing bucket 0x18c5d8 (size 5242880)
SDL_GP2X: InitHWSurfaces
SDL_GP2X: InitHWSurfaces scratch = 0
SDL_GP2X: Creating cursor 16x16
SDL_GP2X: Allocated WMcursor @ 0x18d2b8 (32)
SDL_GP2X: SurfaceManager allocating 256 bytes
SDL_GP2X: SurfaceManager adding new free bucket of 5242624 bytes @ 0x18ce68
SDL_GP2X: SurfaceManager allocated 256 bytes at 0x41100000
SDL_GP2X: SurfaceManager allocating 307200 bytes
SDL_GP2X: SurfaceManager adding new free bucket of 4935424 bytes @ 0x18cea0
SDL_GP2X: SurfaceManager allocated 307200 bytes at 0x41100100
Fatal signal: Segmentation Fault (SDL Parachute Deployed)
SDL_GP2X: Freeing cursor 0x18d2b8
SDL_GP2X: SurfaceManager freeing 256 bytes @ 0x41100000 from bucket 0x18c5c0
SDL_GP2X: VideoQuit
SDL_GP2X: FreeHWSurfaces
SDL_GP2X: Freeing bucket 0x18c5d8 (size 17825792)
SDL_GP2X: Freeing bucket 0x18c5c0 (size 256)
SDL_GP2X: Freeing bucket 0x18ce68 (size 307200)
SDL_GP2X: Freeing bucket 0x18cea0 (size 4935424)
SDL_GP2X: FreeHWSurface 0x18ceb8
SDL_GP2X: SurfaceManager freeing 5242880 bytes @ 0x40000000 from bucket 0x18c484
SDL_GP2X: DeleteDevice
[root@gp2x sd]$
 
In fact, after reading the GP2X SDL wiki, I found that double buffering is not working, so I replaced my SDL_Flip with SDL_UpdateRect(screen, 0, 0, WIDTH, HEIGHT);
Now the program launches! but it's black screen with white tears and weird pixels colors :s
I also tried with SDL_UpdateRect(screen,0,0,0,0); but it's the same
Both vode run fine on a PC build!

And when I kill the app, I can see the background and the sprite well drawn, without errors!

Any idea? I'm still getting closer thanks to your help ;)
 
In fact, after reading the GP2X SDL wiki, I found that double buffering is not working, so I replaced my SDL_Flip with SDL_UpdateRect(screen, 0, 0, WIDTH, HEIGHT);
Now the program launches! but it's black screen with white tears and weird pixels colors :s
I also tried with SDL_UpdateRect(screen,0,0,0,0); but it's the same
Both vode run fine on a PC build!

And when I kill the app, I can see the background and the sprite well drawn, without errors!

Any idea? I'm still getting closer thanks to your help ;)
You say you're creating a sw surface, so yes double buffering won't work (and you shouldn't be setting it either), but that doesn't have anything to do with SDL_Flip. Calling flip on a hw surface with double buffering enabled will flip the buffers, but on a sw surface it just falls back to calling updaterect instead (so no need to change your code). Without seeing all your code it's hard to say what might be going wrong, but I think you've got bigger problems than something being wrong with sdl_flip or sdl_updaterect.
 
Last edited by a moderator:
This is *exactly* what happens to me! See my messages: http://www.gp32x.de/board/index.php?showtopic=34626 and http://www.gp32x.de/board/index.php?showtopic=34459
I think was slightly confused with multiple problems at once but I'm still not able to get all the stuff I need to work.

Charlie


So your solution is, replacing all floats with int?

My soft runs with SDL_DOUBLEBUF | SDL_HWSURFACE, 8bits, but the screen is flickering and the transparencies are garbled (like if there were only 1 transparent pixel out of 2 which is REALLY transparent), and moving sprites are leaving a trail :(
 
Last edited by a moderator:
You say you're creating a sw surface, so yes double buffering won't work (and you shouldn't be setting it either), but that doesn't have anything to do with SDL_Flip. Calling flip on a hw surface with double buffering enabled will flip the buffers, but on a sw surface it just falls back to calling updaterect instead (so no need to change your code). Without seeing all your code it's hard to say what might be going wrong, but I think you've got bigger problems than something being wrong with sdl_flip or sdl_updaterect.

It may have to do with the screen settings... here's the code

header.h

Code:
//#define PC
#define GP2X


// Screen parameters
#ifdef GP2X
#define WIDTH		320
#define HEIGHT		240
#define SCREEN_BPP	8
#define VIDEO_MODE	SDL_DOUBLEBUF | SDL_HWSURFACE
#endif

#ifdef PC
#define WIDTH		640
#define HEIGHT		480
#define SCREEN_BPP	32
#define VIDEO_MODE	SDL_DOUBLEBUF | SDL_HWSURFACE
#endif

[LOTS OF #DEFINE FOR GAME CONSTANTS]

// Headers...
#include<iostream>
#include"SDL.h"
#include <ctime>
using namespace std;

// Custom headers including class and member definitions
#include "player.h"
#include "enemy.h"


here's main.cpp

Code:
#include"header.h"


int main()

{	
	// Initialisation
	SDL_Surface *screen = NULL;
	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER  | SDL_INIT_JOYSTICK);
	screen = SDL_SetVideoMode(WIDTH,HEIGHT,SCREEN_BPP, VIDEO_MODE);
	SDL_JoystickOpen(0);
	SDL_ShowCursor(0);

	// Declaration
	srand((unsigned)time(0));
	SDL_Surface *bg = NULL, *tmp = NULL;
	SDL_Event event;
	bool done = (screen == NULL);

	int nbBot=1, i=0;
	int deadBot=0;
	int timer=0;
	
	// Background image loading
	tmp = SDL_LoadBMP("img/bg.bmp");
	bg = SDL_DisplayFormat(tmp);
	SDL_FreeSurface (tmp);

	// Objects declaration	
	player p(32, 47); // Create the player with sprite's dimension
	enemy *e = new enemy[MAX_BOT];
	
	// Background drawing	
	SDL_BlitSurface(bg, NULL, screen, NULL);

	while(!done)

		{
		timer=SDL_GetTicks();
		deadBot=0;
		
		// Clear the sprites by blitting to the screen part of bg equal to sprite's position and size
		for (i=0; i<nbBot; i++)
			e[i].clear(screen, bg);
		p.clear(screen, bg);
		
		// Manage events
		while(SDL_PollEvent(&event))

			{

			switch(event.type)

				{

				case SDL_QUIT:

					done=true;

					break;
				#ifdef GP2X
				case SDL_JOYBUTTONDOWN:
					switch (event.jbutton.button)
				#endif
				#ifdef PC
				case SDL_KEYDOWN:
					switch (event.key.keysym.sym)
				#endif
						{
						case KEY_QUIT:

							done=true;
							break;
						case KEY_FULL:
							SDL_WM_ToggleFullScreen(screen);
							break;
						// 4 Directions
						case UP:
							p.yVel-=PLAYER_SPEED;
							p.direction=NORD;
							p.moving++;
							break;
						case DOWN:
							[ETC ETC]
						default:
							break;
						}
					break;
				#ifdef GP2X
				case SDL_JOYBUTTONUP:
					switch (event.jbutton.button)
				#endif
				#ifdef PC
				case SDL_KEYUP:
					switch (event.key.keysym.sym)
				#endif
						{
						// 4 Directions
						case UP:
							p.yVel+=PLAYER_SPEED;
							p.moving--;
							p.currentClip=PLAYER_DEFAULT_CLIP;
							break;
						case DOWN:
							[ETC ETC]
						default:
							break;
						}
					break;
				default:

					break;

				}

			}
		// Movements + bots count
		if (p.pos.x < WIDTH-p.pos.w) p.pos.x += p.xVel;
			else if (p.pos.x > WIDTH) p.pos.x += p.xVel;
				else p.pos.x--;
		
		if (p.pos.y < HEIGHT-p.pos.h) p.pos.y += p.yVel;
			else if (p.pos.y > HEIGHT) p.pos.y += p.yVel;
				else p.pos.y--;
				
		for (i=0; i<nbBot; i++)
			if (!e[i].dead) e[i].follow(p, ENEMY_SPEED);
				else deadBot++;

		// Calls for display functions
		for (i=0; i<nbBot; i++)
			e[i].print(screen);
		p.print(screen);
		SDL_Flip(screen); 
		
		// Add a bot
		if (nbBot<MAX_BOT && SDL_GetTicks()%SPAWN_DELAY<10)
			nbBot++;
		// End if no bots remaining
		if (deadBot >= nbBot)
			{
			done=true;
			SDL_Delay(2000);
			}

		// Set the FPS frequency
		else while (SDL_GetTicks()-timer < 1000/FRAME_PER_SECOND);
		}
	
	// Ending

	SDL_FreeSurface(screen);
	SDL_FreeSurface(bg);
	SDL_Quit();
	return EXIT_SUCCESS;

	}



player and enemy are similar classes

Code:
class player
	{
	private:
		SDL_Surface* sprite; // SPRITE SHEET
		SDL_Rect clip[NB_CLIPS_PLAYER][NB_DIRECTIONS_PLAYER]; // RECTS THAT CUT SPRITE SHEET
	public:
		int currentClip; // CURRENT SPRITE PART TO DRAW
		int moving; // Is the player moving? (int and not bool to avoid bug when multiple keys are pressed)
		player(int x, int y); // Constructor takes sprite dimension as parameters
		~player();
		SDL_Rect pos; // PLAYER POSITION
		void print(SDL_Surface *screen); // SIMPLE CALL TO SDL_BlitSurface
		void clear(SDL_Surface *screen, SDL_Surface *bg); SAME AS PRINT, BUT DRAWS BG INSTEAD OF PLAYER
		template<typename T> void follow(T& p, int v); // Object follow another object P with speed V
		
		int xVel, yVel, direction; // Velocity, and which direction the player is facing.
	};

I added some commentaries...
As I told, all is working without any problems if I compile for PC ;)
 
Last edited by a moderator:
So your solution is, replacing all floats with int?
I wish I had a solution that works for all the cases. I have replaced all the floats with longs for fixed point because I was going to do that anyway and that works unless I compile with -static which gives me the black and white bands if it compiles at all. I'm just expressing my sympathetic frustration. If I find a consistant solution rest assured that I will post it.

Cheers,
Charlie
 
Last edited by a moderator:
If I find a consistant solution rest assured that I will post it.
Ok so in one of my other post on this subject I said that I managed to solve some of my problems by re-arranging the order of the arguments to gcc, specifically moving the -l flags to after the list of .o files. Doing a little more re-arranging of arguments and making sure that SDL_SetVideoMode gets called with SDL_HWSURFACE | SDL_DOUBLEBUF seems to have gotten rid of the black and white lines. The command that worked for me with no errors and full prettiness on the gp2x is:
open2x-gcc main.o matrix.o figures.o fixed.o -o bin/wire3d.gpe -lSDL_gfx -msoft-float -lm -lg -lpthread -static `/usr/local/open2x/bin/sdl-config --static-libs`
Note how everything is before the call to sdl-config. I don't know why this works, I'm just happy it does!

I hope this solves your issues as well. Now I can get on with writing some kick-ass games ;)

Cheers,
Charlie
 
Last edited by a moderator:
What toolchains have you installed? Could be you're getting the wrong libs for acceleration in your -static build .. If there are multiple GP2X libSDL*'s around on your system, possibly you're not setting things up for the lib you're linking to .. for example, the accelerated version of SDL for GP2X versus the factory version, etc.
 
i'm using the latest (? probably...) open2x release, downloaded and compiled last week end!

I will try your command this evening charlieb, hope it will work ;) I'm really willing to do something usefull for the GP2X, sooner or later, hope I will succeed ;)
 
I will try your command this evening charlieb, hope it will work ;) I'm really willing to do something usefull for the GP2X, sooner or later, hope I will succeed ;)
Errm well, the command did get the SDL stuff to work statically but the float problem is still around. Maybe more argument re-arranging will solve it. The test program I used doesn't use any floats anymore but I just ran a program that does and I'm back to getting "relocation error: ./boids.gpe: undefined symbol: __floatsisf". Grrrr although it is reasonably likely that this is down to my own incompetance and I'm using an old executable. I'll check this evening.
Maybe someone with more gcc knowledge than I can weigh in on why/how argument order matters or point us at a resource that explains it simply.

Cheers,
Charlie
 
Last edited by a moderator:
I will try your command this evening charlieb, hope it will work ;) I'm really willing to do something usefull for the GP2X, sooner or later, hope I will succeed ;)
Errm well, the command did get the SDL stuff to work statically but the float problem is still around. Maybe more argument re-arranging will solve it. The test program I used doesn't use any floats anymore but I just ran a program that does and I'm back to getting "relocation error: ./boids.gpe: undefined symbol: __floatsisf". Grrrr although it is reasonably likely that this is down to my own incompetance and I'm using an old executable. I'll check this evening.
Maybe someone with more gcc knowledge than I can weigh in on why/how argument order matters or point us at a resource that explains it simply.

Cheers,
Charlie


When you talk about floats, do you mean, declaring floats (like float c = 3,14; ?) or declaring int and dividing them? because I don't explicitly declare any floats, but use divisions (for exemple, spritesheet->width/number_of_sprites to 'cut' my sprite sheet, or sprite_width/2 to have the middle of a sprite)


*edit* another example : else while (SDL_GetTicks()-timer < 1000/FRAME_PER_SECOND);
where FRAME_PER_SECOND is #define @ 60
is THIS a float? or are you talking about declared floats?
 
Last edited by a moderator:
When you talk about floats, do you mean, declaring floats (like float c = 3,14; ?) or declaring int and dividing them? because I don't explicitly declare any floats, but use divisions (for exemple, spritesheet->width/number_of_sprites to 'cut' my sprite sheet, or sprite_width/2 to have the middle of a sprite)


*edit* another example : else while (SDL_GetTicks()-timer < 1000/FRAME_PER_SECOND);
where FRAME_PER_SECOND is #define @ 60
is THIS a float? or are you talking about declared floats?
I'm talking about explicity declared floats. When you divide an int by and int and put the results into an int the compiler will realize that you actually want integer division and no floats will be involved. Both of the examples you give are integer division; actually they are const integer division which is even faster but still no floats. If you wanted to introduce floats you really have to either use a decimal point with your constants (which may still not give you a float depending on the compiler and the exact code) or cast the whole shebang to float: (float)pritesheet->width/(float)number_of_sprites.
This floatlessness can lead to some nasty bugs where you multiply the results of an int division or in general when the result of the division will be close to 1 e.g.
1000 * 9 / 10 = 0 because (int)9 / (int)10 is just 0 whereas (float)1000 * (float)9 / (float)10 = 900 because the intermediate result is 0.9. In any case the best way to be sure that you are compiling some float values into you program is to create a float varible and then use it to ensure it doesn't get optimized away e.g. float var = 1.0; printf("%f", var);

C

P.S. I may have gone a bit over the top with the float casts in my little example. In some languages floatiness is passed through the calculation so 1000 * 10 / 9.0 would be sure to give you 900 (or 900.0). I'm still not sure what the rules in C are so I like to be really, really sure :)
 
Last edited by a moderator:
Back
Top