LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-08-2004, 10:50 PM   #1
elvee
Member
 
Registered: Aug 2004
Distribution: mandrake 10
Posts: 38

Rep: Reputation: 15
sdl .raw image-based map loading


Hi! I am attempting to make an destructable terrain demo using sdl. I made the maps using gimp and saved as .pnm in raw format. Right now the program loaded the images, and using pixel functions, it draws the image. The problem is that it doesnt turn out right. At all. Using 2 test maps, 1 (a 640x480 map) turns out somewhat familiar (but not at all right), and a 60x40 map is totally wrong.

here are screen shots to demonstrate the results:
640x480 map
60x40 map
*the application is DeterraGen. The results are in the deterragen window, and the map is in the gimp window
** the first image isn't completely up to date. The current one will not rotate the image, however it still looks the same (the interlace look that only shows about 1/4 of the picture)

Here is my image loading and printing functions, as well as my pixel function (pixel function from a tutorial, so if it looks familiar, thats why)
Code:
int map::load( const char* path )
{	
	unsigned long wloaded = 0, hloaded = 0;		
	ifstream mapfile(path, ios::binary );
	if( !mapfile )
	{
		return 0;
	}
	mapfile.ignore(255, '\n' );
	mapfile.ignore(255, '\n' );
	mapfile>> width >> height;
	cout<<"width: "<<width<<" height: "<<height<<endl;
	data = new terrain*[width];
	cout<<"map data pointer array initilized.\n";
	for(int i = 0; i< height; i++)
		data[i] = new terrain[width];
	mapfile.ignore(255, '\n' );
	for( int y = 0; y<height; y++)
	{
		for( int x = 0; x<width; x++ )
		{
			char buffer;
			buffer = mapfile.get();
			if( (unsigned short) buffer == 0 ) data[y][x].exists = 0;
			else 
			{
				data[y][x].exists = 1;
			}
			if( wloaded==0 )hloaded++;
		}
		wloaded++;
	}
	cout<<wloaded<<"x"<<hloaded<<" loaded.\n";
	mapfile.close();
	return 1;
}
void map::display( SDL_Surface *screen )
{
#ifdef DEBUG
	cout<<sizeof(terrain)<<endl;
	unsigned short hprinted =0, wprinted =0;
#endif
	for( int y = 0; y < height; y++ )
	{
		for( int x = 0; x < width; x++ )		
		{
//		cout<<x+1<<", "<<y+1<<": "<<data[x][y].exists<<endl;

			if( data[y][x].exists )
			{
				drawPixel( screen, x, y, 255, 255, 255 );
			}
			else  if( !data[y][x].exists )
			{
				drawPixel( screen, x, y, 0, 0, 0 );
			}
#ifdef DEBUG
			if(wprinted==0) hprinted++;
#endif
		}
#ifdef DEBUG
		wprinted++;
#endif
	}
#ifdef DEBUG
	cout<<wprinted<<"x"<<hprinted<<" printed.\n";
#endif
}
Code:
void drawPixel ( SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B )
{
	if( SDL_MUSTLOCK( screen ) ) SDL_LockSurface( screen );
	
	Uint32 color = SDL_MapRGB(screen->format, R, G, B);
	switch (screen->format->BytesPerPixel)
	{
		case 1: // Assuming 8-bpp
		{
			Uint8 *bufp;
			bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
			*bufp = color;
		}
		break;
		case 2: // Probably 15-bpp or 16-bpp
		{
			Uint16 *bufp;
			bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
			*bufp = color;
		}
		break;
		case 3: // Slow 24-bpp mode, usually not used
		{
			Uint8 *bufp;
			bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
			if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
			{
				bufp[0] = color;					
				bufp[1] = color >> 8;
				bufp[2] = color >> 16;
			} else 
			{
				bufp[2] = color;
				bufp[1] = color >> 8;
				bufp[0] = color >> 16;
			}
		}
		break;
		case 4: // Probably 32-bpp
		{
			Uint32 *bufp;
			bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
			*bufp = color;
		}
		break;
	}
	if( SDL_MUSTLOCK( screen ) ) SDL_UnlockSurface( screen );
}
I have spent many hours on this, and it has been VERY frustrating. Can anyone see why the weird results are produced? Can anyone help me fix it?

Last edited by elvee; 09-08-2004 at 10:54 PM.
 
Old 09-09-2004, 11:25 PM   #2
elvee
Member
 
Registered: Aug 2004
Distribution: mandrake 10
Posts: 38

Original Poster
Rep: Reputation: 15
anyone?
 
Old 10-09-2004, 02:03 AM   #3
dixy
LQ Newbie
 
Registered: Oct 2004
Posts: 1

Rep: Reputation: 0
Assuming that your image has the same pixel format like the screen surface you could easely use the following code:

SDL_Surface * loadsurface(char* filename) {
FILE *foo;
void *pixels;
SDL_Surface *loader;
int width;
int height;
int depth;
int pitch;
Uint32 Rmask;
Uint32 Gmask;
Uint32 Bmask;
Uint32 Amask;

foo = fopen(filename, "r");
fread((void *) &width, sizeof(int), 1, foo);
fread((void *) &height, sizeof(int), 1, foo);
cout<<"\n"<<width<<" "<<height;
pixels = (void *) new char(width*height*4);
fread(pixels, width*4, height, foo);
fclose(foo);
loader = SDL_CreateRGBSurfaceFrom(pixels, width, height, screen->format->BytesPerPixel, screen->pitch
, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
return loader;
}


void savesurface(SDL_Surface *pic, char *filename) {
FILE *foo;
foo = fopen(filename, "w+");
fwrite((void *) &pic->w, sizeof(pic->w), 1, foo);
fwrite((void *) &pic->h, sizeof(pic->h), 1, foo);
fwrite(pic->pixels, pic->w*pic->format->BytesPerPixel, pic->h, foo);
fclose(foo);
}


To make your image use the same pixel format the screen has:
temp = SDL_DisplayFormat(screen);

I wish you success.

And don't use fstream, ofstream and ifstream in writing binary data. You'll get them corrupt even if you use open(filename, ios::binary);
If you don't believe me try this:
ofstream foo;
ifstream bar;
char b[100];
int n;
double f;

foo = open("file.data", ios::binary);
foo<<"Hello world!\n"<<175<<12356.4325;
foo.close();

bar = open("file.data", ios::binary);
bar>>b;
bar>>n;
bar>>f;
bar.close();
cout<<"\n"<<b<<n<<f;

What did u see?U can even use bar.get(b,13);bar>>n;bar>>f;

Take a look to the "binary" file file.data. Open it with a text editor. How do u see the int number and the double number written in the file?They appear like binary data?No, they were written like text data even if you used ios::binary flag.

Last edited by dixy; 10-09-2004 at 02:06 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
SDL Image problem.. where do I put... RHLinuxGUY Programming 3 07-23-2005 03:36 AM
x-based applications error while loading kira Linux - Software 2 04-09-2005 11:39 AM
Milkshape file loading - SDL Hyakutake Programming 2 09-28-2004 11:56 AM
Setting X boot image, and loading image untwisted Linux - General 2 03-09-2004 07:40 PM
Anyone got a good Debian based kernel image conf file that I can use slewis1972 Debian 2 07-06-2003 11:26 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:35 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration