Como hacer funcion que devuelva array de punteros a bitmap

Resuelve tus dudas sobre emulación y reconstrucción
User avatar
Chacal
Usuario habitual
Posts: 20
Joined: Sun Dec 31, 2006 2:15 pm
Location: Los Barrios

Como hacer funcion que devuelva array de punteros a bitmap

Postby Chacal » Sat Jan 20, 2007 12:46 pm

Hola, estoy aqui con otro de mis problemas.

Estoy con una función escribiendola en C, que se encargaria de cargar de un fichero bmp, una imagen con tiles, que seran usados para dibujar luego un mapa, entonces, decidi de copiar cada tile de ese archivo en un nuevo BITMAP, concretamente mediante un array o matriz. Entonces, ya tengo hecho perfectamente la copia de esos tiles, el problema es, que esta funcion devuelva ese array con los tiles. Como enrealidad cada elemento del array es un puntero a BITMAP pues hice la funcion asi:

BITMAP * cargar_tileset()
{
...
BITMAP *tileset[MAX_TILES]//Lo de MAX_TILES es una constante que tengo yo en la cabecera
return tileset;
}
(perdonen que no ponga el codigo entero, es que lo tengo en otro ordenador)
Esto me da a mi un error en el compilador diciendo algo de tipo incompatible de puntero a retornar.
He probado a poner BITMAP*[]cargar_tileset() pero ahi ya el compilador se hace un lio dandome miles de errores de sintaxis que no hay, asi que no funciona.

Intentare de llevarme los codigos del ordenador donde los tengo aqui para que les echeis un vistazo, mientras, podria alguen decirme como en teoria se deberia de hacer¿?

NOTA: Uso Allegro y el Dev C++ 5 por si sirve de algo ;)

Muchas gracias!
User avatar
R Granado
Usuario avanzado
Posts: 124
Joined: Fri Jul 25, 2003 10:39 am

Postby R Granado » Sat Jan 20, 2007 2:40 pm

Hola,

El problema que tienes es que has definido la función cargar tiles para devolver un punetro a la estrucutra BITMAP (BITMAP *), pero estas intentando devolver un array de punteros a BITMAP (*tileset[MAX_TILES]) por lo tanto, el tipo es incompatible.

Tampoco creo que debas hacer:

BITMAP * cargar_tileset()
{
BITMAP *tileset[MAX_TILES];
...
return tileset;
}

ya que la variable tileset es local de cargar_tileset(), y cuando la abandones será eliminada sin piedad :twisted:

Te adjunto el siguiente código, usa un "puntero a puntero" que tiene el mismo efecto que un array de punteros.

BITMAP **tileset;

- Primero pides memoria para los punteros de los tiles que quieras almacenar:

tileset = malloc(sizeof(BITMAP *) * MAX_TILES);

- Con esto tendrás el array, después, en el bucle se asignarán los punteros a cada posición con:

tileset = create_bitmap(TILE_W, TILE_H);

- después, devuelves el puntero tileset. Al ser memoria asignada con malloc no es local de la función y no se guardará en la pila, al salir de la función se "desapilarán" las variables globales (incluida tileset)... pero ya estás devolviendo su valor (el puntero) hacia quien te haya llamado.

Prueba el siguiente ejemplo, creo que con unas cuantas modificaciones podrás usarlo :)

Code: Select all

#include <Allegro/allegro.h>

#define MAX_TILES	32
#define TILE_W		16
#define TILE_H		16

BITMAP ** generar_tiles() 
{ 
	int i;
	BITMAP **tileset;
	
	tileset = malloc(sizeof(BITMAP *) * MAX_TILES);
	
	for(i = 0; i < MAX_TILES; i++)
	{
		tileset[i] = create_bitmap(TILE_W, TILE_H);
		clear_to_color(tileset[i], makecol(i * 8, i * 8, i * 8));
	}

	return tileset; 
} 

int main(int argc, const char *argv[])
{
	BITMAP **tiles;
	int i, x, y;

	allegro_init();
	install_keyboard();
	
	set_color_depth(32);	
	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320, 200, 0, 0)) 
	{
		allegro_message("Error setting 320x200x8 gfx mode:\n%s\n", allegro_error);
		return -1;
	}
	
	tiles = generar_tiles();
	
	x = 0;
	y = 0;
	for(i = 0; i < MAX_TILES; i++)
	{
		draw_sprite(screen, tiles[i], x, y);
		
		x += TILE_W;
		if(x >= 320)
		{
			x = 0;
			y += TILE_H;
		}
	}
	
	readkey();
	
	return 0;
}
END_OF_MAIN();
No importa cuantas veces fracase, inténtelo de nuevo
User avatar
Chacal
Usuario habitual
Posts: 20
Joined: Sun Dec 31, 2006 2:15 pm
Location: Los Barrios

Postby Chacal » Sat Jan 20, 2007 3:12 pm

Muchisimas gracias R Granado, veo que no es posible retornar un array de punteros en una funcion, asi que optare por hacer puntero a punteros, como tu me has explicado, claro que al hacer un malloc y poner el tamaño de los BITMAP* multiplicado por el numero de tiles tenemos el espacio para almacenar todas las tiles, lo que hariamso al hacer un array tiles[num_tiles].
Lo que veo tambien es que una vez fuera el `puntero, ¿lo puedo tratar como un array no? voy a probarlo :P .

Intente llevarme aqui el codigo que lo tengo en mi otro ordenador, pero el unico modo de sacarlo de ahi es por disquetes y no tengo :(, es que es mi viejo ordenador un P 200MHZ de 16 de RAM :P de la prehistoria ya casi jaja, y lo tengo ahi en mi cuarto que es el que uso para programar y tres o cuatro cositas mas. Bueno, asi me aseguro de que el juego no me coma demasiados recursos y vaya perfecto en ordenadores mas grandes jijiji. En cuanto encuentre un disquete (tengo que tener alguno por aqui reboleao XD) pongo el codigo como me ha quedado, y te cuento que tal va.

Gracias de nuevo, Saludos!!!
From the 16-Bit era...
Image
Guest

Postby Guest » Sat Jan 20, 2007 6:22 pm

Chacal wrote:... Lo que veo tambien es que una vez fuera el `puntero, ¿lo puedo tratar como un array no? voy a probarlo :P .
Sí, puedes usar los punteros como vectores, al igual que las cadenas de char. Por ejemplo:

char test = "foo";

test[0] es 'f'
test[1] es 'o'
test[2] es 'o' (la segunda)

En tu caso no tendrás variables char, sino los punteros a BITMAP. Puedes tratar cualquier variable en C de la manera que te de la gana haciendo el casting apropiado... aunque no te recomiendo hacerlo ya que es muy fácil complicarse la vida :!:
User avatar
R Granado
Usuario avanzado
Posts: 124
Joined: Fri Jul 25, 2003 10:39 am

Postby R Granado » Sat Jan 20, 2007 6:25 pm

El de arriba era yo :oops:
User avatar
Chacal
Usuario habitual
Posts: 20
Joined: Sun Dec 31, 2006 2:15 pm
Location: Los Barrios

Postby Chacal » Thu Jan 25, 2007 7:00 pm

Funciona perfectamente, gracias! Ahora tengo que seguir por como mostrar cual mapa por cada nivel.
Aqui dejo el codigo de como me quedo, esto es una prueba de las funciones, las cuales estoy modificando de nuevo para adaptarlas a mi juego (un comecocos)

Code: Select all

#include <allegro.h>
#define TILE_W      16
#define TILE_H      16
#define RES_W       640
#define RES_H       480
#define MAP_W       40
#define MAP_H       30
#define MAXTILES    64
BITMAP *buffer,*mapa;

void init();
void deinit();


int map[30][40] = 
{
    {1,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,2},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6},
    {3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4}
};

BITMAP **carga_tileset()
{
     BITMAP *ftiles;
     PALETTE tilepal;
     if((ftiles = load_bmp("tileset.bmp", tilepal)) == NULL)
     {
        allegro_message("No se pudo cargar el tileset");
        exit(-1);
     }
     int cortes;
     cortes = ftiles->w/TILE_W;
     BITMAP **tileset;
     tileset = malloc(sizeof(BITMAP*)*MAXTILES);
     int i;
     for(i=0;i<MAXTILES;i++)
     {
         tileset[i] = create_bitmap(TILE_W,TILE_H);
         blit(ftiles,tileset[i],i*TILE_W,0,0,0,TILE_W,TILE_H);
     }
     return tileset;                   
        
}

void mostrar_tileset(int tile, BITMAP **tileset)
{
     draw_sprite(buffer,tileset[tile],(SCREEN_W/2)-tileset[tile]->w,(SCREEN_H/2)-tileset[tile]->h);
}
BITMAP* dibujar_mapa(BITMAP**tileset,int map[MAP_H][MAP_W])
{
    BITMAP *mapa;
    mapa = create_bitmap(MAP_W*TILE_W,MAP_H*TILE_H);
    int linea;
    int columna;
    int tile;
    for(linea=0;linea<MAP_H;linea++)
    {
        for(columna=0;columna<MAP_W;columna++)
        {
           tile = map[linea][columna];
           blit(tileset[tile],mapa,0,0,columna*TILE_W,linea*TILE_H,TILE_W,TILE_H);
        }
    }
    return mapa;  
}




int main() {
	init();
	buffer = create_bitmap(RES_W,RES_H);
    int tile = 0;
	BITMAP **tileset;
	BITMAP *mapa;
    tileset = carga_tileset();
	mapa = dibujar_mapa(tileset,map);
    while (!key[KEY_ESC]) {
	      clear_bitmap(buffer);
          masked_blit(mapa,buffer,0,0,0,0,640,480);
          //mostrar_tileset(tile, tileset);
          blit(buffer,screen,0,0,0,0,RES_W,RES_H);
          if(key[KEY_0])tile = 0;	
          if(key[KEY_1])tile = 1;
          if(key[KEY_2])tile = 2;
          if(key[KEY_3])tile = 3;
          
	}

	deinit();
	return 0;
}
END_OF_MAIN()

void init() {
	int depth, res;
	allegro_init();
	depth = desktop_color_depth();
	if (depth == 0) depth = 32;
	set_color_depth(depth);
	res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
	if (res != 0) {
		allegro_message(allegro_error);
		exit(-1);
	}

	install_timer();
	install_keyboard();
	install_mouse();
	/* add other initializations here */
}

void deinit() {
	clear_keybuf();
	/* add other deinitializations here */
}
Un Saludo!
From the 16-Bit era...
Image

Return to “Consultas”

Who is online

Users browsing this forum: No registered users and 2 guests