Consulta con unload_wav (esto no es un bug)

Started by FreeYourMind, October 04, 2009, 11:04:49 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

FreeYourMind

Hola.
Despues de darle varias vueltas al problema, pensando que era un problema de memoria en la Wiz,
resulta que en el PC tambien ocurre, o sea acabo de encontrar un Bug en el uso de 'unload_wav'.

Ya se que Splinter me va decir que no lo es :), pero para mi solo dejara de serlo cuando en lugar de un crash total te ponga un mensaje de error en la consola :)


Descripción:
-----------

1 - Imaginemos que tenemos 5 ficheros audio declarados en el juego.


2 - En un determinado momento hacemos


unload_wav(snd_1);
unload_wav(snd_2);
unload_wav(snd_3);
unload_wav(snd_4);
unload_wav(snd_5);


3 -

Ahora tenemos 2 casos:


Caso A - Funcional:

Anteriormente solo hemos cargado el snd_1, o sea, con la sentencia anterior descargamos el snd_1 que esta en memória, y los otros como aún no han sido cargados
tampoco vamos tener problemas, ya que Bennu no da error por hacer un unload a un sonido que aún no hemos cargado, esto es bueno porque nos permite poner sentencias de unload genéricas sin preocuparnos que en ese punto del programa no esten todos esos sonidos en memória.


Caso B - Crash:

Anteriormente cargamos el snd_1, snd_1 = load_wav("Musica2.wav");, depues le hicimos un unload_wav(snd_1), acto seguido cargamos los sonidos snd_2 y snd_3 respectivamente (no es necesario decir que despues de cargar sonidos se ponen tocando y que antes de descargar sonidos los paramos),
hasta aqui todo fenomenal, pero ahora al ejecutar de nuevo el unload a los 5 sonidos, el unload_wav(snd_1) nos va petar Bennu,
me imagino que como ya antes habiamos echo un unload_wav(snd_1), nos peta porque repetimos el unload a un fichero inexistente en memória, y à diferencia de los sonidos snd_4 y snd_5 que nunca fueron cargados, el snd_1 tendra algun identificador ya guardado por Bennu que le indica que ya fue cargado anteriormente provocando el error.


La solucion es facil, hacer el unload_wav sólo si sabemos que el sonido aún se encuentra en memória, ahora pregunto, como se puede saber que un determinado processo esta activo ?

Como ya se que por ejemplo durante el enemigo final el snd_1 ya no existe, y así identificando que el enemigo aún esta vivo ya no haria el unload_wav(snd_1) porque ya sabia que se le habia echo el unload antes.

Gracias de antemano.












DCelso

no entiendo el por qué haces dos unload al sonido 1.
A ver, normalmente cargas el sonido antes del bucle principal y descargas el sonido después del bucle principal. Asi que descargar el sonido por el medio no tiene sentido a no ser que vayas a cargar justo despues otro porque quieras cambiarlo, lo que tienes que hacer es revisar el código y ponerlo de otra forma para que solo se ejecute un unload_wav(snd1)
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

DCelso

De todas formas, prueba a poner la variable snd1 a 0 después de hacer el unload, por si cuela y al hacer el siguiente unload se da cuenta de que ya no hay sonido cargado. Un poco chapu pero puede que funcione.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

FreeYourMind

Esto es para reportar el problema del crash, la solucion ya la tengo, pongo un flag 'snd_1_cargado=true' cuando lo carge y a false cuando lo libere.

Despues solo hay que poner:

IF (snd_1_cargado=true) unload_wav(snd_1);


Esto de los unloads lo hago aprovechando lo de que hacer un unload a un sonido que aún no existe no hace nada.

Porque esto se hace en el continue (que es el mismo procedimiento en todas las fases), o sea si terminas el juego durante la fase 1 se hace el unload a la musica 1 en el continue 1 vez, pero si llegas al enemigo final, el enemigo final hace el unload tambien a la musica 1 para poner la suya (hago esto porque tengo la wiz a tope de memoria y sino no tengo memória suficiente), y claro esta, si pierdes en el enemigo tambien te vas al continue que vuelve a hacer unload a la musica 1.

:)

Drumpi

No estoy seguro, pero creo que si haces unload_wav con el parámetro 0 descarga todos los wavs de memoria, sin embargo, si descargas un ID de wav no válido... no debería dar crash (¿o si?), al menos que no haga nada, pero claro, con un ID desconocido podría hacer cualquier cosa, pasa lo mismo (creo, no lo he probado) con unload_map, unload_fpg, unload_fnt, delete_text...
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

FreeYourMind

Ya he cambiado todo el código, parece que ya funciona bien, me estaba asustando despues de cambiar todo, tanto daba tener la flag a false o true que el unload se ejecutaba siempre, al final con 'doble igualdad' ya funciona:

IF (snd1_in_memory == true) unload_wav(snd1); snd1_in_memory = false; END


Solo me queda ver una cosilla, he echo un

write(0, 160, 120, 4, snd1_in_memory);

que imprime 0 si es false o 1 si es true (poniendo con 'offset snd1_in_memory' el true imprime 00914EA4)

y parece que el boss cuando aparece el codigo que ejecuta en su procedimiento:

unload_wav(snd1);
snd1_in_memory = false;


y resulta que parece que no me esta cambiando la variable booleana de true a false!!
Lo tengo que mirar mejor a ver que puede ser !!! es raro sin duda, la variable nada tiene que ver con el sonido, es solo una variable.

FreeYourMind

Bueno ya encontre el fallo, la variable si se actualizaba , el wrtie text era el que no se actualizaba ;)

Ya marcha todo perfecto.

Como conclusión , no estaria mal que esto se tratara a nivel interno, ignorando el unload era la mejor solución, pero poniendo mensaje en la consola tambien era mejor que el crash :)

Saludos.

SplinterGU

no, no es un bug... y por favor antes de poner "BUG", primero por favor has una consulta y chequea que asi sea...

tu problema no es de un bug de bennu, es de un problema de programacion basica... si usas handles invalidos el lenguaje no tiene porque darte un error... pidele a C hacer algo con un area de memoria no alocada, o hacer algo con un area de memoria que ya has liberado... y veras que pasa...

esta mal eso que dices de que al no retornar error te puedes despreocupar del handle que la pasas... eso es un error, el que no retorne parametros, solo significa que no nos interesa el valor de retorno...

el error no es ni funcional ni conceptal... el error es tuyo...

renombro el tema... saludos
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Ok, pero se podria tratar para que saliera de Bennu y poniera un mensaje, como ocurre en más situaciones, fijate que Bennu esta pensado para gente con pocos conocimientos, y el mensaje te ayudaria mucho aparte de decirte cual era el problema sin tener que buscar código a lo loco para encontrar el problema.

DjSonyk

Buenas, yo te recomendaria poner identificadores a todo lo que vallas a cargar en memoria , tal como ID_Sonido1=Load_Wav(...); ect
Ya que te sera tambien mas facil a la hora de programar las cargas y descargas de memoria pues en vez de estar mirando una y otra vez el numero del codigo donde se carga solo tiene que hacer un Un_load ( Id_Sonido1),aparte que ademas te permite poder hacer comprobaciones de estado tal y como te indica FreeYourMind ... If (Id_Sonido1==True) Unload_Wav(Id_Sonido1); ect
Saludos.

SplinterGU

bennu actualmente esta pensado para gente iniciada y gente avanzada... a diferencia de fenix, bennu no aborta ante situaciones de error, da la posiblidad al programador a recuperar la situacion... por eso, cuando un sonido se carga debes chequear el retorno, ahora si vos mandas a hacer una operacion sobre algo invalido (no NULL) entonces no hay forma de evitar el cuelgue... tener una tabla de referencias (que implica una busqueda) de que hay cargado y que no, es un overhead adicional que no podemos permitir... es mas simple una variable de facil accceso desde el programa .prg.

DjSonyk, eso que vos pusiste es codigo prg (controlable por el programador), lo que FreeYourMind indica es otra cosa... el dice que bennu debe decir si un handle es valido o invalido...

bennu solo hace chequeos por NULL, pero si vos le pasas algo no NULL, se considera un valor valido, se considera que el programador sabe lo que hace... poner un chequeo de eso significa, levantar una tabla en memoria para mantener las referencias de que se aloca y que no, y realizar las busquedas en esas tablas cada vez que alguien manda una operacion de sonido, lo que implica consume de memoria y consumo extra de cpu, ambas cosas no son aceptables.

saludos.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Tampoco pido que sea eso, con tratar la excepción en el punto que Bennu hace crash (tirando de un ejemplo que provoque ese error) bastaria, por lo menos ya sabias que era error de unload_wav.

SplinterGU

puedes correr el programa con -d y ver donde cae...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

Por lo general, cada vez que se cae (o se me ha caido) tanto Bennu como Fenix me ha dado el error:
SDL segmentation fault.
Parachute deployed

Es un error que empiezo a odiar ;D Prefería cuando wiendows sacaba esa ventana de "error interno" con la biblia en hexadecimal, decías "ottia, casi me cargo el windows... lástima" :D
Lo que pasa es que ese error te sale por la ventana de comandos, si lo ejecutas con doble clic, arrastrar o creo que desde un IDE, no te va a salir nada. Con Linux si si lo escribes en un script, es muy sencillo.

bgdi tuprograma.dcb >log.txt 2>error.txt
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)