Anuncios Google

Tutorial 05 Introducir una imagen en el ejecutable

Tutoriales Avanzados Homebrewes

Hola a todos. Este nuevo tutorial parte de la idea del anterior, por no decir que es el mismo :-). Pero como os comente en el anterior tutorial, hay muchas formas de cargar imagenes para luego mostrarlas en la pantalla de la PSP y Unicorn me dijo una vez que le interesaria poder introducir las imagenes dentro del codigo para que nadie pudiera modificarlas y se que muchos de vosotros teneis la misma inquietud, asi que de eso va este nuevo tutorial. Os recordamos que, una vez entreis al tutorial, disponeis del menu izquierdo para moveros sobre capitulos.

Vamos a cargar una imagen igual que en el anterior tutorial lo unico que esta pasara a formar parte del ejecutable de esta manera nadie podra modificarla.

Tambien vamos a incorporar una nueva libreria: la libreria SDL_image.h, la cual nos permitira cargar casi cualquier archivo de imagen como JPG,BMP,PNG,etc.. al contrario que la libreria SDL.h que solo nos permitia cargar archivos BMP.

Dicho esto vamos a ponernos manos a la obra ;-)

Lo primero que necesitamos es el programa gpbinconv que encontrareis en el archivo adjunto a este tutorial (solo usuarios registrados) junto con el codigo fuente que vamos a usar durante todo este tutorial. Este archivo lo que hace es trasformar una imagen en un archivo de cabecera que incluiremos en nuestro codigo, de esta manera la imagen pasara a formar parte de dicho codigo y ya no tendremos que adjuntar la imagen al ejecutable de nuestra aplicacion.

Una vez que lo ejecutemos nos saldra este ventana

Tras lo cual nos colocamos en la parte de arriba donde pone SOURCE y le damos a la casilla de la derecha donde pone EXPLORE. Nos saldra la siguente ventana en la que seleccionamos el archivo de imagen que queremos trasformar

Nosotros para este tutorial vamos a trasformar una imagen PNG que son las que uso yo normalmente para mis juegos y aplicaciones. La imagen tiene el nombre de Fondo.png. Una vez que la seleccionemos la pantalla quedara asi

y pasaremos al segundo recuadro donde pone DESTINATION(.H) y le damos al recuadro de la derecha donde pone EXPLORE y nos saldra una ventana como la anterior, pero con una peculiaridad que esta en vez de para cargar una imagen es para salvar la imagen en un determinado fichero en formato C:

En este tutorial le vamos a dar el nombre de gfx.h. Como habeis podido ver en la ventana anterior, en la zona que pone nombre ahi escribis el nombre que querais que tenga el archivo seguido de .h y pulsais en GUARDAR, tras lo cual la ventana se cerrara y volveremos a la pantalla principal del programa, la cual quedara de esta manera

El siguiente paso es muy simple solo tendreis que poner un nombre a la tabla o array que va a mantener la imagen. Esto lo hacemos escribiendo el nombre que queramos en el siguiente cuadro: donde pone ARRAY NAME mas simple imposible :-). Yo como vereis en la siguiente imagen le he puesto el nombre de GfxFondo (tened mucho cuidado en esta parte con las mayusculas y la minusculas pues tal como lo escribais lo teneis que poner luego en el codigo para cargar la imagen)

Lo ultimo que nos queda hacer con este programa es darle al boton de la derecha donde pone CONVERT y listo una vez que termine de convertir la imagen, lo cual tardara mas o menos dependiendo del procesador, pero que en todos los casos no sera mas de unos segundos ,os aparecera la siguiente pantalla

Le damos a ACEPTAR y listo, ya tendremos creado nuestro archivo de cabecera en la direccion que hayamos puesto a la hora de guardarlo con el nombre de gfx.h. Cerramos el programa y listo.

Ahora vamos a meternos con el archivo makefile, en el cual tendremos que modificar un par de lineas como hicimos en el tutorial anterior, asi como poner la nueva libreria que vamos a usar.

TARGET = TUTORIAL05
 
PSPSDK = $(shell psp-config --pspsdk-path)
 
PSPBIN = $(PSPSDK)/../bin
 
 
 
OBJS = main.o
 
 
JOY = YES
 
CFLAGS = -Wall -Wno-long-long -G0 -O2 -DJOY_$(JOY)
 
CFLAGS += $(shell $(PSPBIN)/sdl-config --cflags)
 
 
 
LIBS = -lSDL_image -lpng -ljpeg -lz -lSDL $(shell $(PSPBIN)/sdl-config --libs)
 
 
 
EXTRA_TARGETS = EBOOT.PBP
 
PSP_EBOOT_TITLE = TUTORIAL05
 
 
 
include $(PSPSDK)/lib/build.mak

solo hay 3 lineas distintas que son

TARGET = TUTORIAL05
 
PSP_EBOOT_TITLE = TUTORIAL05
 
LIBS = -lSDL_image -lpng -ljpeg -lz -lSDL $(shell $(PSPBIN)/sdl-config --libs)

Las 2 primeras lineas como os explique en el segundo tutorial cambian el nombre del proyecto y el nombre que se muestra en la PSP. Como veis es logico que las haya cambiado, dado que se trata de un nuevo proyecto, sino no sabriamos cual cargar en la PSP si tubieramos los dos proyectos en nuestra Stick ;-)

En la tercera linea hemos incluido la Libreria nueva que vamos a usar SDL_image, precedida de -l (la ralla horizontal seguida de una l minuscula) y las librerias PNG,JPG y Z (las librerias png,jpg y z las incluimos por que las necesita la libreria SDL_image para funcionar) para que el compilador sepa que tiene que buscar dichas librerias.

Una vez explicados los cambios en el archivo makefile vamos a pasar a explicar el codigo el cual es exactamente igual al del tutorial numero 04, pero modificando una linea en el codigo la cual hace la carga en memoria de la tabla o array que contine la imagen y la inclusion de 2 archivos de cabecera, uno el que acabamos de crear y otro con la nueva libreria que vamos a usar.

Pero antes teneis que abrir el archivo de cabecera que acabamos que crear con un editor de textos. Yo por ejemplo uso el UltraEdit pero podeis usar cualquier otro, dado que no vamos a modificar nada en este archivo, solo vamos a apuntar una cantidad que necesitaremos luego para cargar la imagen en nuestro codigo. Mirad, en la siguiente captura teneis señalado en rojo la cantidad que tenemos que apuntar. Esta cantidad cambia de un archivo a otro dependiendo de lo grande que sea la imagen que hemos trasformado o del numero de colores que tenga la misma. Este numero es la cantidad de memoria que se come dicha imagen.

Explicado esto ya podemos ponernos manos a la obra y mirar el codigo

#include <pspkernel.h>
#include <sdl.h>
#include <sdl_image.h>
#include <gfx.h>
 
int main(){
SDL_Surface *Imagen,*PantallaV;
SDL_Event Evento;
SDL_Init(SDL_INIT_VIDEO);
SDL_ShowCursor(0);
PantallaV = SDL_SetVideoMode(480,272,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
Imagen = IMG_Load_RW(SDL_RWFromMem(GfxFondo,199821), 0);
SDL_BlitSurface(Imagen,NULL,PantallaV,NULL);
SDL_Flip(PantallaV);
SDL_FreeSurface(Imagen);
while (SDL_WaitEvent(&Evento))
{
if (Evento.type == SDL_QUIT) {
SDL_FreeSurface(PantallaV);
break;
}
}
return 0;
}

Las 2 primeras lines ya nos iran sonando un poco con ellas. Lo que hacemos es cargar estas dos librerias PSPKERNEL y SDL sin las cuales no nos funcionaria el programa. En el tutorial anterior os explique lo que hacia cada una mas o menos.

#include <pspkernel.h>
#include <sdl.h>

Ahora ademas cargamos la libreria SDL_image y nuestro archivo de cabecera el que acabamos de crear. Esto lo hacemos con las siguientes lineas.

#include <sdl_image.h>
#include <gfx.h>

La libreria PSPKERNEL como os comente en el anterior tutorial hay que incluirla en todos los programas que hagamos para PSP, pues se encarga de las funciones internas de KERNEL de la PSP.

La libreria SDL es la que nos interesa es la encargada de todo el tema grafico y sonoro y poco a poco en esta serie de tutoriales explicaremos la mayoria de las funciones que la integran.

La libreria SDL_image es la encargada de suministrarnos mas opciones a la hora de cargar imagenes que SDL no puede darnos, por ejemplo la posibilidad de cargar archivos JPG,PNG,Etc..

Tras esto llegamos a un viejo conocido de todos nosotros:

int main(){

Como creo que todos los que estais mirando esto habreis visto ya algun programa en C, sabreis que el MAIN es la funcion por la que empiezan todos o casi todos los programas en C, asi que no nos detendremos mas en el y pasemos a la siguiente linea, la cual nos define Imagen y PantallaV como punteros de SDL_Surface que traducido a palabras mas o menos normales nos define PantallaV e Imagen como si fueran folios en blanco sobre los que podremos pintar o cargar imagenes, asi como mostrarlos por pantalla

SDL_Surface *Imagen,*PantallaV;

La siguiente funcion lo que hace es definir Evento como una estructura de eventos. Lo usaremos para almacenar los eventos del sistema, las pulsaciones de teclas y demas. Yo no lo suelo usar en mis proyectos, prefiero usar para controlar las teclas las funciones especificas de PSP, las cuales ya veremos en sucesivos tutoriales.

SDL_Event Evento;

En la siguiente linea de codigo Inicializamos el modo de video de la PSP para poder pintar sobre la pantalla.

SDL_Init(SDL_INIT_VIDEO);

Una vez que hemos inicializado el modo de video, debemos esconder el cursor que aparece en la esquina superior izquierda de la pantalla para que no nos estorbe, pues queda bastante feo tapando nuestro maravilloso fondo. Para ello usamos la siguiente linea de codigo.

SDL_ShowCursor(0);

Tras lo cual estaremos listo para definir PantallaV como la pantalla Principal de la PSP. Por eso le damos las dimensiones de la pantalla de la PSP, osea 480X272. Tambien le decimos que vamos a usar la pantalla en modo 32 bits color real. Con SDL_HWSURFACE le decimos que cree la superficie en la menoria de video. Si quisieramos crear la superficie o papel en blanco en la memoria normal usariamos esto SDL_SWSURFACE y con SDL_DOUBLEBUF le decimos que la cree con doble buffer. Con esto lo que conseguimos es eliminar ese parpadeo molesto a la hora de refrescar las imagenes por pantalla.

PantallaV = SDL_SetVideoMode(480,272,32,SDL_HWSURFACE|SDL_DOUBLEBUF);

Una vez que tenemos definida PantallaV, lo siguiente que hacemos es cargar la imagen, para ello usamos la siguiente linea de codigo.

Imagen = IMG_Load_RW(SDL_RWFromMem(GfxFondo,199821), 0);

Esta linea es la encargada de cargar los datos del archivo de cabecera que creamos antes para poder mostrarlos por la pantalla de la PSP. En los parentesis interiores es donde tenemos que colocar los datos del archivo de cabecera. En el primer punto el nombre que le pusimos al array o tabla cuando creamos el archivo que si os acordais era GfxFondo Imagen = IMG_Load_RW(SDL_RWFromMem(GfxFondo,199821), 0); y en el segundo la cantidad que apuntamos anteriormente del archivo de cabecera que acabamos de crear Imagen = IMG_Load_RW(SDL_RWFromMem(GfxFondo,199821), 0);. Una vez fuera de estos parentesis vemos un numero el cual siemple tiene que ser 0 Imagen = IMG_Load_RW(SDL_RWFromMem(GfxFondo,199821),0); y listo. Con esto tenemos todos los datos del archivo de cabecera dentro de Imagen. Tras esto solo nos que da pasarlo a la pantalla de la PSP, lo cual es posible gracias a las siguentes 2 lineas de codigo.

SDL_BlitSurface(Imagen,NULL,PantallaV,NULL);
SDL_Flip(PantallaV);

La primera linea copia todo el contenido de Imagen en PantallaV y la segunda linea Muestra PantallaV en la Pantalla de la PSP. Nos vemos obligados a copiar el contenido de Imagen en PantallaV por que hemos definidos con anterioridad a PantallaV como la pantalla de la PSP. Tras hacer esto ya no necesitamos Imagen para nada, asi que con la siguiente linea de codigo liberamos la memoria que teniamos reservada para Imagen. Esto es una buena practica de programacion: cuando no necesitamos mas una cosa la liberamos de memoria para que no nos estorbe consumiendonos memoria.

SDL_FreeSurface(Imagen);

Y para finalizar nuestro querido bucle, el cual os explique en el anterior tutorial y que os vuelvo a explicar. Siento ser pesado pero es que quiero que queden claros los conceptos al principio por que luego no voy a explicar todo el codigo en cada Tutorial ;)

while (SDL_WaitEvent(&event))
{
if (event.type == SDL_QUIT) {
SDL_FreeSurface(PantallaV);
break;
}
}

La primera funcion del bucle es la que hace el bucle while (SDL_WaitEvent(&event)). Esto hace una pregunta, que mientras SDL_WaitEvent(&event) sea cierto, osea 1 o mayor de 1 se ejecute la parte que esta dentro de las llaves del bucle, osea la siguiente funcion.

if (event.type == SDL_QUIT) {
SDL_FreeSurface(PantallaV);
break;
}

La cual es otra pregunta, que si event.type es igual a SDL_QUIT que se ejecute la parte de codigo entre las llaves; y si no es cierto que siga adelante. En caso de que sea cierto pues se liberia la memoria reservada para PantallaV. Esto lo hacemos con la funcion SDL_FreeSurface(PantallaV); y tras liberar la memoria se rompe el bucle con la funcion break; y asi llegamos al final del programa y por lo tanto salimos de el.

Para que event.type sea igual a SDL_QUIT tenemos que haber pulsado HOME y dicho que si a la pregunta de que si queremos salir del programa.

Y para terminar solo nos queda devolver 0 al main dado que main es una funcion de tipo int espera que le devolvamos un valor a la hora de concluir la funcion, sino a la hora de compilar el codigo nos salda un warning avisandonos de ello y por eso con la siguiente linea de codigo le devolvemos 0. No tiene ninguna utilidad pero bueno todo sea por usar un tipo de programacion mas correcto. XD

return 0;

Tras esto terminamos el tutorial y estamos preparados para el siguiente :). Solo quiero pediros disculpas por mi desaparicion del mundo de la escene durante estos 3 meses, pero he tenido problemas personales y me a sido imposible ponerme delante de un PC, pero ahora que he vuelto espero que sigais todos hay apoyando mi trabajo y el de tantos otros como yo que intentamos daros lo mejor para vuestra PSP.

Nos vemos en el Proximo Tutorial y espero que estos tutoriales os sirvan de ayuda. Cualquier duda que tengais postearlas en este mismo hilo o mandarmelas por privado que intentare ayudaros con lo que sea.

Un saludo
Kaltorak.

4.785715
Tu voto: Ninguno Votos totales: 4.8 (14 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Hola, el tutorial es muy

Hola, el tutorial es muy bueno y me ha salido bien.

 

Pero cuando meto el eboot en la psp y lo ejecuto, no me sale la imagen, alguien me podría decir porque?

No me sale me aparece este

No me sale me aparece este error:

$ make
psp-gcc -I. -IC:/PSPDev/psp/sdk/include -Wall -Wno-long-long -G0 -O2 -DJOY_YES -
I/usr/local/include/SDL -Dmain=SDL_main -I/usr/include/mingw -DWIN32 -Uunix -mno
-cygwin -D_PSP_FW_VERSION=150 -c -o main.o main.c
cc1.exe: error: unrecognized command line option "-mno-cygwin"
make: *** [main.o] Error 1


Imagen de kaltorak

Lo estas compilando con el

Lo estas compilando con el cygwin ?

 

Si claro

Si claro

Imagen de david_gv

muchas gracias por el tuto,

muchas gracias por el tuto, pero me e descargado la libreria y al compilar tu ejemplo me da error, podrias subir la ke usaste tu aver si eske me la e descargado mal?
gracias y saludos


[img]http://img137.imageshack.us/img137/3500/mehishdvna9.png[/img]

Imagen de kaltorak

Hola david_gv

Que libreria es la que te da el fallo exactamente ??

Imagen de david_gv

SDL_image.h

SDL_image.h

Imagen de kaltorak

esta libreria la tienes que

esta libreria la tienes que instalar cuando instalas el cygwin como puse en tutoriales anteriores.

Imagen de -Ermac-

Muy bueno

Muy bueno me parece muy util

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.