Jump to content
  • Advertisement
Sign in to follow this  
Zeophlite

[SDL] SDL_CreateRGBSurface errors [SOLVED]

This topic is 4844 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to convert an existing image to a new file that contains map data I take 2 images, one of map data, and another of the actual image This code converts the image to the map
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SDL.h"

Uint32 getpixel(SDL_Surface *surface, int x, int y) {
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;

    case 2:
        return *(Uint16 *)p;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
        return *(Uint32 *)p;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }
}

void SLock(SDL_Surface *screen) {
	if(SDL_MUSTLOCK(screen)) {
		if(SDL_LockSurface(screen) < 0 ) {
			return;
		}
	}
}

void SUnlock(SDL_Surface *screen) {
	if(SDL_MUSTLOCK(screen)) {
		SDL_UnlockSurface(screen);
	}
}

void DrawIMG(SDL_Surface *img, SDL_Surface *screen, int x, int y) {
	SDL_Rect dest;
	dest.x = x;
	dest.y = y;
	SDL_BlitSurface(img, NULL, screen, &dest);
}

SDL_Surface * ImageLoad(std::string file) {
	return ImageLoad(file, -1, 0, 0, 255);
}

SDL_Surface * ImageLoad(std::string file, Uint8 alpha) {
	return ImageLoad(file, -1, 0, 0, alpha);
}

SDL_Surface * ImageLoad(std::string file, int r, int g, int b) {
	return ImageLoad(file, r, g, b, 255);
}

SDL_Surface * ImageLoad(std::string file, int r, int g, int b, Uint8 alpha) {
	LogTxt("Loading Image: " + file);
	SDL_Surface *temp1, *temp2;
	temp1 = SDL_LoadBMP(file.c_str());
	
	if(r >= 0) {
		SDL_SetColorKey(temp1, SDL_SRCCOLORKEY, SDL_MapRGB(temp1->format, r, g, b));
	}
	
	if(alpha < 255) {
		SDL_SetAlpha(temp1, SDL_SRCALPHA, alpha);
		temp2 = SDL_DisplayFormatAlpha(temp1);
	} else {
		temp2 = SDL_DisplayFormat(temp1);
	}
	
	SDL_FreeSurface(temp1);
	return temp2;
}



SDL_Surface *screen, *mapfile, *datafile;


int main(int argc, char *argv[]) {
	if(argc != 2) {
		printf("Bounce Map Maker:\nUsage\n%s [mapname]\n", argv[0]);
		exit(1);
	}
	
	if(SDL_Init(SDL_INIT_VIDEO) < 0) {
		printf("Couldn't initialize SDL: %s\n", SDL_GetError ());
		exit(1);
	}
	atexit(SDL_Quit);
	
	screen = SDL_SetVideoMode (640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
	if(screen == NULL) {
		printf("Couldn't set 640x480x32 video mode: %s\n", SDL_GetError ());
		exit(1);
	}
	SDL_WM_SetCaption ("Bounce Map Maker", NULL);
	
	std::string outfile;
	outfile = argv[1];
	outfile = outfile + ".map.bmp";
	mapfile = ImageLoad(outfile.c_str());
	DrawIMG(mapfile, screen, 0, 0);
	SDL_Flip(screen);
	outfile = argv[1];
	outfile = outfile + ".data.bmp";
	datafile = ImageLoad(outfile.c_str());
	
	int width = mapfile->w;
	int height = mapfile->h;
	
	unsigned char r = 0, g = 0, b = 0;
	Uint32 pix;
	
	FILE *fp;
	outfile = argv[1];
	outfile = outfile + ".mfb";
	if((fp = fopen(outfile.c_str(), "w")) == NULL) {
		printf("Couldn't open output file");
		exit(1);
	}
	
	fwrite(&width, sizeof(int), 1, fp);
	fwrite(&height, sizeof(int), 1, fp);
	
	SLock(mapfile);
	SLock(datafile);
	int i, j;
	for(i = 0; i < width; i++) {
		for(j = 0; j < height; j++) {
			pix = getpixel(mapfile, i, j);
			SDL_GetRGB(pix, mapfile->format, &r, &g, &b);
			
			fwrite(&r, sizeof(unsigned char), 1, fp);
			fwrite(&g, sizeof(unsigned char), 1, fp);
			fwrite(&b, sizeof(unsigned char), 1, fp);
			
			pix = getpixel(datafile, i, j);
			SDL_GetRGB(pix, datafile->format, &r, &g, &b);
			
			fwrite(&r, sizeof(unsigned char), 1, fp); // PixelData
		}
	}
	
	SUnlock(datafile);
	SUnlock(mapfile);
	
	fclose(fp);
	
	if(screen != NULL) {
		SDL_FreeSurface(screen);
	}
	if(mapfile != NULL) {
		SDL_FreeSurface(mapfile);
	}
	if(datafile != NULL) {
		SDL_FreeSurface(datafile);
	}
	
	return 0;
}



And this code converts the data back

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <vector>
#include <string>

#include "SDL.h"
#include "Tools/sdl-common.h"

class CMap {
	public:
		bool init(std::string mapfile, SDL_Surface *m_screen);
	
	protected:
		SDL_Surface *mapImage, *screen;
		std::vector<std::vector<bool> > solid;
		int width, height;
};

bool CMap::init(std::string mapfile, SDL_Surface *m_screen) {
	screen = m_screen;
	
	FILE *fp;
	if((fp = fopen(mapfile.c_str(), "r")) == NULL) {
		LogTxt("Couldn't open mapfile: " + mapfile + "\n");
		return false;
	}
	
	fread(&width, sizeof(int), 1, fp);
	fread(&height, sizeof(int), 1, fp);
	
	SDL_Surface *tmpmap;
	unsigned char data[width*height*4];
	unsigned char pixdata;
	
	solid.resize(width);
	int i, j;
	for(i = 0; i < width; i++) {
		for(j = 0; j < height; j++) {
			solid.push_back(false);
		}
	}
	
	for(i = 0; i < width; i++) {
		for(j = 0; j < height; j++) {
			fread(&data[(i*height+j)*4], sizeof(unsigned char), 1, fp); // red
			fread(&data[(i*height+j)*4+1], sizeof(unsigned char), 1, fp); // green
			fread(&data[(i*height+j)*4+2], sizeof(unsigned char), 1, fp); // blue
			data[(i*height+j)*4+3] = 255;
			fread(&pixdata, sizeof(unsigned char), 1, fp); // PixelData
			if(pixdata == 128) {
				solid[j] = true;
			} else {
				solid[j] = false;
			}
		}
	}
	
	fclose(fp);
	
	Uint32 rmask,gmask,bmask,amask;
	if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
		rmask = 0xff000000;
		gmask = 0x00ff0000;
		bmask = 0x0000ff00;
		amask = 0x000000ff;
	} else {
		rmask = 0x000000ff;
		gmask = 0x0000ff00;
		bmask = 0x00ff0000;
		amask = 0xff000000;
	}
	
	if((tmpmap = SDL_CreateRGBSurfaceFrom(&data, width, height, 32, width*4, rmask, gmask, bmask, amask)) == NULL) {
		LogTxt("tmpmap == NULL - Bad"); // + mkstr(
	} else {
		LogTxt("tmpmap != NULL - Good"); // + mkstr(
	}
	if((mapImage = SDL_DisplayFormat(tmpmap)) == NULL) {
		LogTxt("mapImage == NULL - Bad"); // + mkstr(
	} else {
		LogTxt("mapImage != NULL - Good"); // + mkstr(
	}
	SDL_FreeSurface(tmpmap);
	
	if(mapImage == NULL) {
		LogTxt("mapImage == NULL - Bad"); // + mkstr(
	} else {
		LogTxt("mapImage != NULL - Good"); // + mkstr(
	}
	
	DrawIMG(mapImage, m_screen, 0, 0);
	SDL_Flip(m_screen);
	SDL_Delay(5000);
	
	return true;
}



The original map picture is here: http://vicious.sixlabs.org/test.map.bmp and the map data is here: http://vicious.sixlabs.org/test.data.bmp My output is this: http://vicious.sixlabs.org/output.bmp Basically the first image is meant to be the same as the third I'm thinking that the problem is to do with (i*height+j)*4 [Edited by - Zeophlite on August 12, 2005 6:46:12 AM]

Share this post


Link to post
Share on other sites
Advertisement
You don't tell what the problem is and your images aren't loading properly, but you might change the part of code like this and see if it helps:


unsigned int pos;
for(i = 0; i < height; i++) { //note: height comes first
for(j = 0; j < width; j++) {
pos=(i*width+j)*4;
fread(&data[pos], sizeof(unsigned char)*3, 1, fp); // red, green & blue
data[pos+3] = 255;


Share this post


Link to post
Share on other sites
Thanks all,
The correct code is now:

for(i = 0; i < width; i++) {
for(j = 0; j < height; j++) {
fread(&data[(j*width+i)*4], sizeof(unsigned char), 1, fp); // red
fread(&data[(j*width+i)*4+1], sizeof(unsigned char), 1, fp); // green
fread(&data[(j*width+i)*4+2], sizeof(unsigned char), 1, fp); // blue
data[(j*width+i)*4+3] = 255;
fread(&pixdata, sizeof(unsigned char), 1, fp); // PixelData

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!