[psp]volver a la pantalla anterior (SDL)

Hola a todos.
Me gustaria poder volver al estado anterior de una pantalla.
O sea, me explico.
Yo tengo una pantalla con dibujitos muy bonito inicial, (le llamaremos pantalla inicio).

En la pantalla inicio le meto muchas imagenes digamos superpuestas. Y queda en un estado X.
como puedo guardar este estado X, para mas adelante poder recuperla?

Luego en ella sobre la marcha voy sobreponiendole imagenes, grafics, letras ..etc... Pero un momento dado, me gustaria volver al estado de la "pantalla inicio", al estado digamos X.

Contando con que la pantalla incio esta compuesta por varias imagenes y simbolos.

Resumiendo, es saber si se puede guardar la "screen", para que cuando me de la gana pueda llamarla.

preguntas:
1.-
como puedo guardar este estado X, para mas adelante poder recuperla?

2.-
Si se puede guardar, como recuperarla?


muchas gracias a todos.
yo crearía una estructura de estado con funciones para guardar y recuperar... pero bueno eso ya al gusto de cada uno.
Una forma muy chapuza es sacar un screen, guardarlo y luego recargarlo, eso sólo en el caso de que necesites sólo la imagen (por ejemplo para algun efecto, como un fade)

Si no necesitas la imagen, entonces lo que no entiendo es que si compones la primera vez la pantalla... ¿por qué no puedes recomponerla una segunda vez? En ese caso yo creo que el problema es que te hace falta un tutorial para programar una máquina de estados.
Como este, por ejemplo ;)
Gracias por vuestras respuestas.
Ante todo se me olvidó. lo quiero hacer con SDL.
yo lo que hago es esto:

SDL_Surface *screen;
SDL_Surface *anteri;
SDL_Surface *table;
screen = SDL_SetVideoMode(480,272,32, SDL_HWSURFACE );
.... meto imagenes en "screen"
table = IMG_Load ("imagenes/tithorver.png");
destino.x = 280; destino.y = 136;
SDL_BlitSurface(table, NULL, screen, &destino);
SDL_FreeSurface(table);
---mas imagenes
---mas imagenes
SDL_BlitSurface(screen, NULL, anteri, &destino); guardo el estado en anteri. aqui LE llamo estado "INICIO"
------------------------------------------------------------------
------------------------------------------------------------------
....sigo metiendo imageness....
tablo = IMG_Load ("imagenes/titsigue.png");
destino.x = 280; destino.y = 136;
SDL_BlitSurface(tablo, NULL, screen, &destino);
SDL_FreeSurface(tablo);
.... mas imagenes encima.
------------------------------------------------------------------
.... en un momento dado, quiero volver al estado "INICIO"
yo lo hago asi, pero no funciona:
SDL_BlitSurface(anteri, &destino, screen, &destino);


---------------------------------------------------------------------
no sé si me explicado bien.
Necesito ayuda.
Muchas gracias por vuestra paciencia.
yo esque no entiendo lo que quieres... te refieres a tener imagenes en memoria? o en pantalla?

aun así mi idea sería crearte una funcion para cada estado(o metodo) y a partir de ahí la llamas cuando la necesites, es posible que te toque hacer secciones es decir algo como IniciarEstado(1); finalizarestado(1); para cargar y descargar imagenes de memoria.

luego para dibujarlas puedes hacer una función dibujarestado(x);

enga suerte
Gracias saulotmalo.
Lo que yo quiero es...mira por ejemplo:
paso 1.
dibujas un fondo. (screen)
pones una imagen de muchas cuadriculas encima.
pones mas imagenes sobre el fondo.
pones mas imagenes sobre el fondo
paso 2.
Escribes un cuadrito en una cuadricula.
paso 3.
mueves ese cuadrito con la flecha dcha hacia la cuadricula de al lado, pero tienes que hacer desaparecer el cuadrito de la cuadricula anterior y dejar lo que estaba en esa cuadricula anterior, antes de que pusieras el cuadrito anterior.

en resumen, es mover un cuadrito por unas cuadriculas (especie de cursor)

todo eso con SDL y para PSP

no se si ahora está mas claro.
Perdonad mi posible mala explicacion.
Muchas gracias.
Por lo que entiendo al principio compones el tablero de juego a partir de varias imágenes.
Luego tienes un 'sprite' que es el que vas a mover, y para ello primero lo borras (redibujando la parte del fondo ocupada por el sprite) y luego dibujas el sprite encima del fondo en la nueva posición.

Ok, lo que puedes hacer es esto:

creas una nueva superficie fondo.
Todas las imágenes del paso 1 las bliteas al fondo.
Esto lo puedes hacer en la precarga, antes de mostrar nada en pantalla.

Una vez compuesto el fondo bliteas el fondo a la screen, para empezar a mostrar algo en pantalla.
Bliteas el sprite en la posición adecuada.

Cuando quieras mover el sprite tienes que:
-coges la posición y el rectángulo ocupado por el sprite, y con esa información bliteas esa porción del FONDO a la superficie screen. Con esto lo que consigues es dejar el fondo igual que cuando terminaste tu paso1, y el sprite está borrado. Pero sólo haces un blit del trozo ocupado por el sprite. Por supuesto podrías redibujar el fondo completamente a la screen, y quedaría igualmente borrado, pero sería muy ineficiente.
-Una vez borrado actualizas la posición del sprite y lo bliteas de nuevo a la superficie screen en su nueva posición.

Dicho de otro modo, compones el fondo en una superficie adicional en memoria para luego poder borrar el sprite.

Si quieres ahorrar memoria, lo que puedes hacer es liberar las múltiples imágenes que utilizas para componer el fondo, una vez compuesto.
muchas gracias Zheo.
Me has dado luz.
Efectivamente me has explicado exactamente lo que quiero hacer.

y lo he intentado implementar y me sale pantalla en negro y no salen las imagenes. como si nno cargara nada screen.
te pongo el codigo resumido, con este mismo codigo me sale pantalla negra.

A ver si me puede ayudar, por favor.
main.c:
#include
#include
#include
#include
#include

#ifdef PSP
#include
#include
#include
#include
#endif

SceCtrlData pad;

int exit_callback(int arg1, int arg2, void *common) {
sceKernelExitGame();
return 0;
}
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}
return thid;
}

SDL_Event event;
SDL_Surface *screen;
SDL_Surface *fondo;
SDL_Surface *table;
SDL_Rect destino;

int main(int argc, char *argv[]){

int done = 0;

if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
printf ("NOse puedo Inicializar SDL: %s\n", SDL_GetError());
exit (1);
}

screen = SDL_SetVideoMode(480,272,32, SDL_HWSURFACE );
fondo=SDL_CreateRGBSurface(SDL_HWSURFACE,480,272,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);
if(!screen){
printf("No se pudo iniciar la pantalla: %s\n", SDL_GetError());
SDL_Quit();
exit(-1);
}

rellena_fondo();
//aqui serian mas llamdas a funciones de carga de imagenes sobre fondo.
//hasta aqui la precarga.

destino.x = 0; destino.y = 0;
SDL_BlitSurface(screen, NULL, fondo, &destino); //aqui vuelco (bliteo) fondo sobre screen para visualizarse

while (done == 0) {
// Comprobando teclas para opciones
sceCtrlReadBufferPositive(&pad, 1);
while (SDL_PollEvent(&event)) {
// Cerrar la ventana
if (event.type == SDL_QUIT) { done = 1; }
}
}
SDL_Quit();
sceKernelExitGame();
exit(0);
//printf("\nTodo ha salido bien.\n");
return 0;
}

int rellena_fondo(){
//pone la imagen del fondo
table = IMG_Load ("imagenes/background.png");
destino.x = 0; destino.y = 0;
SDL_BlitSurface(table, NULL, fondo, &destino);
SDL_FreeSurface(table);
}




muchas gracias de antemano.
Así a bote pronto, es normal que la pantalla esté en negro, ya que te has olvidado de blitear el fondo a la superficie de pantalla ^_^
zheo escribió:Así a bote pronto, es normal que la pantalla esté en negro, ya que te has olvidado de blitear el fondo a la superficie de pantalla ^_^


rellena_fondo();
muchas graciasss.
De veras muy agradecidooo.
Ya está solucionado.
Otra batalla ganada.
Y todo gracais a vosotros.
Aun me falta la guerra entera.

muchas gracias, continuo con mi pequeño hbk.
saulotmalo escribió:
rellena_fondo();

Tú ves que rellena_fondo() blitee algo en la pantalla?

En realidad lo hace unas líneas más abajo con
SDL_BlitSurface(screen, NULL, fondo, &destino); //aqui vuelco (bliteo) fondo sobre screen para visualizarse

No lo pude mirar con total detenimiento porque estaba en el curro, y no era plan :P

Por cierto, cuál era el problema al final eldelpuerto?
yo tambien estaba en el curro y estoy :P

[code]
int rellena_fondo(){
//pone la imagen del fondo
table = IMG_Load ("imagenes/background.png");
destino.x = 0; destino.y = 0;
SDL_BlitSurface(table, NULL, fondo, &destino);
SDL_FreeSurface(table);
}
[\code]

amos a mi me parece que está bliteando en la funcion rellena_fondo... ahora bien no he podido mirar el código con detenimiento.
sabes.. lo que hice fué coger el main.c y lo dejé pelao. (antes lo copié claro)
y que fuera haciendo lo que me deciais.
me funcionó.
Y así fui metiendole mas cosas poco a poco y probando.
sonido, fuentes. mas imagenes.
Y asi ya me funcionó.
muchas gracias de nuevo.
saulotmalo escribió:yo tambien estaba en el curro y estoy :P

[code]
int rellena_fondo(){
//pone la imagen del fondo
table = IMG_Load ("imagenes/background.png");
destino.x = 0; destino.y = 0;
SDL_BlitSurface(table, NULL, fondo, &destino);
SDL_FreeSurface(table);
}
[\code]

amos a mi me parece que está bliteando en la funcion rellena_fondo... ahora bien no he podido mirar el código con detenimiento.

Pero está bliteando a fondo, que es una superficie aparte de la pantalla, está haciendo lo que le comenté unos posts más arriba.

Lo raro es que no encuentro el fallo en el código original :S que rucazo...
cierto, no miré de donde venian las variables ;) son los peligros de que venga el jefe
si, loq ue hice fue blitear a fondo todo las imagenes digamos de principio.
Luego de fondo a screen.
Y segui metiendo imagenes.
Luego en un momento dado, pues pillo el trozo de fondo que me interesa y lo meto en screen, (en el mismo lugar claro).
ME abristeis los ojos.
Lo del error es que yo tampoco sabia de donde venia el error.
eL main.c reducido me lo dejaba todo negro, no supe ver de donde venia el problema.(misterio).

Ahora en esa cuestion..problema subsanado.
Seguiré molestadoos un poco.
Un saludo, y muchas graciasss.
16 respuestas