Problema con punteros... creo

Consulte acerca de programas, técnicas, algoritmos etc.

Problema con punteros... creo

Notapor baco » Dom Jul 12, 2009 5:28 pm

Hola:

Hace mucho que no me pasaba por aqui pero tocaba antes intentar aprender como funciona SDL xD

Tengo un problema que creo que es de punteros (aunque no estoy muy seguro ya que voy aprendiendo todo sobre la marcha)

El error que me da al compilar es:
Código: Seleccionar todo
error: no se puede convertir 'SDL_SUrface**' a 'SDL_Surface*' para el argumento '1' para 'void imprimirBaldosas(SDL_Surface *, SDL_Surface *, Uint8, Uint8, Uint8, Uint8)'


Y aqui parte del codigo relacionado:
Código: Seleccionar todo
void  cargarImagenes(SDL_Surface ** imagen, const char *ruta);
void imprimirBaldosas(SDL_Surface *pantalla, SDL_Surface *title, Uint8 mapaColumna, Uint8 mapaFila, Uint8 titleColumna, Uint8 titleFila);

int main() {

    SDL_Surface *pantalla;       // Definimos una superficie

    SDL_Surface *baldosasSuelo;
   cargarImagenes(&baldosasSuelo, "imagenes/tiles/modificado.png");

    SDL_Surface *baldosasSueloAmpliada;

    baldosasSueloAmpliada=rotozoomSurface(baldosasSuelo,BALDOSA_ROTAR,BALDOSA_AMPLIAR,1);


    int i, j;
    for(i=0;i<BALDOSA_AREA_ALTO;i++)
          {
          for(j=0;j<BALDOSA_AREA_ANCHO;j++)
             {
         // imprimir mapa en el buffer
         imprimirBaldosas(&pantalla, &baldosasSueloAmpliada, j, i, 0, 1); // <--- la linea del error es esta
             }
          }

}

// funciones
void  cargarImagenes(SDL_Surface ** imagen, const char * ruta)
   {
   *imagen = IMG_Load(ruta);

   if (*imagen == NULL)
      {
      error(3);
      }
   }

void imprimirBaldosas(SDL_Surface *pantalla, SDL_Surface *title, Uint8 mapaColumna, Uint8 mapaFila, Uint8 titleColumna, Uint8 titleFila)
   {
   // establezco el cuadrado donde se pegara la baldosa
   SDL_Rect posicionEnPantalla;
   posicionEnPantalla.x = mapaColumna * BALDOSA_ANCHO;
       posicionEnPantalla.y = mapaFila * BALDOSA_ALTO;
       posicionEnPantalla.w = VENTANA_ANCHO;
       posicionEnPantalla.h = VENTANA_ALTO;
       
       
   // establezco el trozo de la imagen que se vera
   SDL_Rect trozoImagen;
   trozoImagen.x = BALDOSA_ANCHO * titleColumna; // 4 +
   trozoImagen.y = BALDOSA_ALTO * titleFila;
   trozoImagen.w = BALDOSA_ANCHO;
   trozoImagen.h = BALDOSA_ALTO;
   
   // Copiamos la imagen en la superficie principal
       SDL_BlitSurface(title, &trozoImagen, pantalla, &posicionEnPantalla);
   }


Si compilo comentando la linea de error
Código: Seleccionar todo
imprimirBaldosas(&pantalla, &baldosasSueloAmpliada, j, i, 0, 1); // <--- la linea del error es esta
deja de dar el error

¿Alguna ayuda para que esa funcion deje de tirar error?
baco
 
Mensajes: 7
Registrado: Lun Sep 22, 2008 4:48 pm

Notapor Juanxo » Dom Jul 12, 2009 6:26 pm

buenas baco:

A lo mejor estoy equivocado, pero en mi opinión el error no está en ese punto, si no en tu definición de la carga de imagenes. No se a ciencia cierta, pero creo que te sobra un '*' en la surface que tienes puesta en la funcion: SDL_Surface *imagen.
Otra manera si no, sería quitarle el & al parametro baldosaSueloAmpliada en la llamada a la función. Creo que con alguna de esas dos cosas debería funcionar
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor baco » Dom Jul 12, 2009 8:10 pm

Nada, me da mas errores.

Como el código que tengo todavía es pequeño casi que lo pego entero por si es de otro punto:

main.cpp
Código: Seleccionar todo
#include <stdio.h>
#include <SDL/SDL.h>             // Incluimos la librería SDL

/**********************************************/
/* añadiendo librerias adicionales          */
/**********************************************/
#include <SDL/SDL_image.h>
#include <SDL/SDL_rotozoom.h>

/**********************************************/
/* definiendo las opciones de la ventana    */
/**********************************************/
#define VENTANA_ANCHO 800 // 640
#define VENTANA_ALTO 600 // 480
#define VENTANA_PROFUNDIDAD_COLOR 24 // 8=256 colores, 16, 24=color real y 32=se destinan a canales alfa
#define VENTANA_PARAMETROS_ADICIONALES SDL_HWSURFACE|SDL_DOUBLEBUF // SDL_FULLSCREEN=pantalla completa |SDL_FULLSCREEN
#define VENTANA_NOMBRE "Imagenes sobre el fondo"
#define VENTANA_RATON_VER 1 // 1=si; 0=no

/**********************************************/
/* caracteristicas de las baldosas          */
/**********************************************/
#define BALDOSA_ANCHO 32 // 32
#define BALDOSA_ALTO 32 // 32
#define BALDOSA_AMPLIAR 2.0 // 2.0
#define BALDOSA_ROTAR 0.0 // 0.0
#define BALDOSA_AREA_ANCHO 19
#define BALDOSA_AREA_ALTO 15

SDL_Surface * iniciar_sdl();
void  cargarImagenes(SDL_Surface **imagen, const char *ruta);
void error(int error);
void imprimirBaldosas(SDL_Surface *pantalla, SDL_Surface *title, Uint8 mapaColumna, Uint8 mapaFila, Uint8 titleColumna, Uint8 titleFila);

int main() {

    SDL_Surface *pantalla;       // Definimos una superficie
    SDL_Event evento;            // Definimos una variable de eventos

    // Inicializamos SDL
    pantalla = iniciar_sdl();
    if (pantalla == NULL) return 1;

   // cargamos la iamgen de prueba
   SDL_Surface *baldosasSuelo;
   cargarImagenes(&baldosasSuelo, "imagenes/tiles/modificado.png");

       // Establecemos el color de la transparencia
   SDL_SetColorKey(baldosasSuelo, SDL_SRCCOLORKEY|SDL_RLEACCEL,\
          SDL_MapRGB(baldosasSuelo->format, 0, 255, 0));
 
    //ampliada BALDOSA_AMPLIAR y giro 0.0 grados con smooth
    SDL_Surface *baldosasSueloAmpliada;

   baldosasSueloAmpliada=rotozoomSurface(baldosasSuelo,BALDOSA_ROTAR,BALDOSA_AMPLIAR,1);
         
    int i, j;
    for(i=0;i<BALDOSA_AREA_ALTO;i++)
          {
          for(j=0;j<BALDOSA_AREA_ANCHO;j++)
             {
         // imprimir mapa en el buffer
         imprimirBaldosas(&pantalla, &baldosasSueloAmpliada, j, i, 0, 1);
             }
          }
    // Mostramos la pantalla "oculta" del búffer
    SDL_Flip(pantalla);

    // Bucle infinito
    for(;;) {
    // Consultamos los eventos
   while(SDL_PollEvent(&evento)) {
       if(evento.type == SDL_QUIT) // Si es de salida
      return 0;
      
      // se activa cuando pulsamos una tecla
      if(evento.type == SDL_KEYDOWN) {   
         if(evento.key.keysym.sym==SDLK_ESCAPE) // salimos al pulsar la tecla ESC
            {
            return 0;
            }
         }
      }
    }

}

            /**********************************************/
            /* arrea para las funciones             */
/*************************************************************************************/

// inicializar SDL       
SDL_Surface * iniciar_sdl()
   {
   SDL_Surface * pantalla;

   if(SDL_Init(SDL_INIT_VIDEO) < 0)
      {
      // En caso de error
      error(1);
      }

    atexit(SDL_Quit); // Al salir, cierra SDL
   
   // Establecemos el modo de pantalla
   pantalla = SDL_SetVideoMode(VENTANA_ANCHO, VENTANA_ALTO, VENTANA_PROFUNDIDAD_COLOR, VENTANA_PARAMETROS_ADICIONALES);
   
   if(pantalla == NULL)
      {
      // Si no hemos podido inicializar la superficie
      error(2);
      }

   // Personalizamos el título de la ventana
   SDL_WM_SetCaption(VENTANA_NOMBRE, NULL);
   
   // oculta el raton
   if(!VENTANA_RATON_VER) SDL_ShowCursor (SDL_DISABLE);

   return pantalla;
}
       
// cargar imagenes
void  cargarImagenes(SDL_Surface **imagen, const char * ruta)
   {
   *imagen = IMG_Load(ruta);

   if (*imagen == NULL)
      {
      error(3);
      }
   }

// escribe en un archivo de texto plano el error que ha salido
void error(int error)
   {
   FILE *archivo;
     archivo=fopen("error.log", "w");
     
   switch(error)
      {
      case 1:
         {
         fprintf(archivo, "Error al inicializar SDL: %s\n", SDL_GetError());
         break;
         }
      case 2:
         {
         fprintf(archivo, "Error al crear la superficie: %s\n", SDL_GetError());
         break;
         }
      case 3:
         {
         fprintf(archivo, "Error al cargar la imagen: %s\n", SDL_GetError());
         break;
         }
      default:
         {
         fprintf(archivo, "%s\n", SDL_GetError ());
         break;
         }
      }
   
     fclose(archivo);
         
   exit(1);
   }

// imprimir el mapa
void imprimirBaldosas(SDL_Surface *pantalla, SDL_Surface *title, Uint8 mapaColumna, Uint8 mapaFila, Uint8 titleColumna, Uint8 titleFila)
   {
   // establezco el cuadrado donde se pegara la baldosa
   SDL_Rect posicionEnPantalla;
   posicionEnPantalla.x = mapaColumna * BALDOSA_ANCHO;
       posicionEnPantalla.y = mapaFila * BALDOSA_ALTO;
       posicionEnPantalla.w = VENTANA_ANCHO;
       posicionEnPantalla.h = VENTANA_ALTO;
       
       
   // establezco el trozo de la imagen que se vera
   SDL_Rect trozoImagen;
   trozoImagen.x = BALDOSA_ANCHO * titleColumna; // 4 +
   trozoImagen.y = BALDOSA_ALTO * titleFila;
   trozoImagen.w = BALDOSA_ANCHO;
   trozoImagen.h = BALDOSA_ALTO;
   
   // Copiamos la imagen en la superficie principal
   SDL_BlitSurface(title, &trozoImagen, pantalla, &posicionEnPantalla);
   }


PD: Cuando lo ejecutaba sin funciones (todo el código revuelto) funcionaba pero al ir 'ordenándolo' y llegar a 'imprimirBaldosas()' se ha jodido
PD2: Lo compilo en Ubuntu usando:
Código: Seleccionar todo
g++ -o main main.cpp -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer -lSDL_net -lSDL_gfx
baco
 
Mensajes: 7
Registrado: Lun Sep 22, 2008 4:48 pm

Notapor baco » Lun Jul 13, 2009 6:29 pm

Al final si que era un '&' (en realidad dos). El que decías y el de pantalla.

Ahora cambiando:
Código: Seleccionar todo
imprimirBaldosas(&pantalla, &baldosasSueloAmpliada, j, i, 0, 1);


por
Código: Seleccionar todo
imprimirBaldosas(pantalla, baldosasSueloAmpliada, j, i, 0, 1);


Ya compila y se ejecuta bien.

Gracias :wink:

PD: Si alguien me explica porque no he podido pasar el parámetro por referencia (con el &) se lo agadecería
baco
 
Mensajes: 7
Registrado: Lun Sep 22, 2008 4:48 pm

Notapor Juanxo » Lun Jul 13, 2009 11:01 pm

Es que en el tema de punteros, ese operador hace referencia a la direccion de memoria a la que apunta, no es que pases el parámetro como tal por referencia(puedes cambiar la direcciona la que apunta pantalla, pero no los valores de pantalla)
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Geo » Mar Jul 14, 2009 6:06 am

baco escribió:PD: Si alguien me explica porque no he podido pasar el parámetro por referencia (con el &) se lo agadecería

Los punteros son variables que almacenan la dirección de la variable a la cual apuntan. De esta forma, podríamos considerar que una dirección de memoria es un puntero.

Como la variable pantalla ya ha sido declarada como un puntero a SDL_Surface:
Código: Seleccionar todo
SDL_Surface* pantalla;


La función imprimirBaldosas espera como primer parámetro un puntero a SDL_Surface. Sin embargo, al intentar hacerlo de esta forma:
Código: Seleccionar todo
imprimirBaldosas( &pantalla... );

estás intentando pasar la dirección de la variable pantalla, dicha variable es un puntero y, por tanto, contiene una dirección que apunta a un tipo SDL_Surface. Es decir, estás usando dos direcciones: la dirección de la variable pantalla (&pantalla), y la dirección que contiene la variable pantalla (los punteros almacenan direcciones).
Como dijimos antes, una dirección de memoria es un puntero y, por lo tanto, estás creando un doble puntero a SDL_Surface, por ello te lanza el error, intentas pasar un SDL_Surface** (puntero doble) cuando la función espera recibir un SDL_Surface* (puntero simple).

Resumiendo, para una función que espera recibir un puntero como parámetro:

Código: Seleccionar todo
void funcion( tipo* parametro );

Estas son las diferentes formas posibles de pasar un parámetro a dicha función:
Código: Seleccionar todo
algo var1;
tipo* var2;

funcion( &var1 );  // correcto, pasa la dirección de var1
funcion( var2 );  // correcto, var2 ya es una dirección
funcion( var1 );  // incorrecto, intenta pasar un valor, no una dirección
funcion( &var2 );  // incorrecto, intenta pasar un doble puntero
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor baco » Jue Jul 16, 2009 9:01 pm

Gracias. Yo confundía la propia variable con el puntero
baco
 
Mensajes: 7
Registrado: Lun Sep 22, 2008 4:48 pm


Volver a General

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron