Bennu Game Development

Foros en Español => General => Topic started by: josebita on February 21, 2011, 02:28:31 PM

Title: Bug en load_fnt() en la Wii
Post by: josebita on February 21, 2011, 02:28:31 PM
Comento esto por si alguien puede echarme una mano a resolverlo.
Estoy intentando resolver el tema de que el código Bennu actual no es capaz de cargar fuentes en plataformas bigendian.
Más o menos, la carga falla en el fichero modules/mod_map/file_fnt.c cuando hace la comprobación:
[code language="c"]if ( chardata.fileoffset == 0 || chardata.width == 0 || chardata.height == 0 )[/code] y el caracter está vacío.
En una fuente que le he mangado a Pixel para hacer pruebas (ésta (http://code.google.com/p/pixjuegos/source/browse/trunk/pixbros/fnt/intro.fnt)) los primeros caracteres están vacíos (width=height=0, como lo confirmo en la carga en linux).
Sin embargo, al ir a cargar en la Wii, la carga falla y los valores (que deberían ser 0 en chardata) son ahora:
[code language="c"]i=0; chardata[0].fileoffset=16843010, chardata[0].width=33686018, chardata[0].height=33686018, bpp=8.[/code]
Hay algunas cosas curiosas sobre esos números que no sé si serán relevantes o no, pero la verdad es que me huelen raro:

¿Alguien tiene alguna idea de qué está pasando?. ¿Por qué está fallando la carga?. Llevo unas cuantas horas con esto y la verdad es que no entiendo nada... El código Bennu parece correcto.
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 21, 2011, 02:57:42 PM
fijate en el arrange.h, si lo esta detectando bien...

fijate si no le falta una condicion a este bloque


    #if defined(__hppa__) || \
        defined(__m68k__) || \
        defined(mc68000) || \
        defined(_M_M68K) || \
        (defined(__MIPS__) && defined(__MISPEB__)) || \
        defined(__ppc__) || \
        defined(__POWERPC__) || \
        defined(_M_PPC) || \
        defined(__sparc__)
        #define __BYTEORDER  __BIG_ENDIAN
    #else
        #define __BYTEORDER  __LIL_ENDIAN
    #endif


y si esto esta fallando, seguramente a la SDL tambien le falta lo mismo...

aunque lo dudo, pero con chequearlo no se pierde nada.
Title: Re: Bug de endianess en load_fnt()
Post by: josebita on February 21, 2011, 03:06:27 PM
Sí, eso funciona sin problemas. Le tuve que añadir una condición más para que me detectara la plataforma sin añadirle un define a mano:
[code language="C"]#if defined(__hppa__) || \
       defined(__m68k__) || \
       defined(mc68000) || \
       defined(_M_M68K) || \
       (defined(__MIPS__) && defined(__MISPEB__)) || \
       defined(__ppc__) || \
       defined(__POWERPC__) || \
       defined(_M_PPC) || \
       defined(__sparc__) || \
       defined(GEKKO)
       #define __BYTEORDER  __BIG_ENDIAN
   #else
       #define __BYTEORDER  __LIL_ENDIAN
   #endif[/code]
También le añadí una rutina para hacer el swap por ensamblador en PPC, he comprobado que ese no sea el problema usando la función con código C normal, también.
Me tiene bastante mosca el asunto este...
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 21, 2011, 03:38:44 PM
en que plataforma estas teniendo este problema?

ese GEKKO es un define tuyo o es nativo de una plataforma?
Title: Re: Bug de endianess en load_fnt()
Post by: josebita on February 21, 2011, 04:00:43 PM
La plataforma es la Wii, que es un PPC bigendian. GEKKO es el nombre genérico de la plataforma que usa GCC y es un define automático.
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 21, 2011, 04:56:56 PM
a ver... analicemos... evidentemente no es tema de los ARRANGE, ya que un arrange de 0, es 0... por favor, quita la parte del asm y usa el codigo que esta en los define... por otro lado, fijate si en el codigo no tenes una cadena (en cualquier orden y en hexa) con los siguientes valores  0x01, 0x01, 0x01, 0x02 (que es 16843010)  y 0x02, 0x02, 0x02, 0x02 (que es 33686018).

me suena a la data del font, seguro que no cambiaste el tipo de ningun puntero ni nada en el codigo de los fonts?

te recomiendo que quites el asm que pusiste y hagas uso de las funciones, dudo que sea eso, pero para ir quitando opciones.
Title: Re: Bug de endianess en load_fnt()
Post by: josebita on February 22, 2011, 04:53:43 PM
Luego lo pruebo. A mí tb me huele a que está leyendo del fichero en el sitio que no es, pero no sé....
Sólo una cosa: se me ocurre que probablemente podamos recrear el bug en plataformas little-endian añadiéndolas al ifdef que has puesto más arriba de forma que se compile con el flag "#define __BYTEORDER  __BIG_ENDIAN".
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 22, 2011, 08:06:58 PM
no, no creo, porque todo se interpretara diferente y lo que obtendremos sera un bonito crash.
Title: Re: Bug de endianess en load_fnt()
Post by: josebita on February 22, 2011, 11:36:46 PM
Vale, al final no es bug de endianess.

Resulta que en el fichero modules/mod_map/file_fnt.c, función gr_load_fnt(), se hace un file_open con el modo "rb". Eso significa que se pide que se abra el fichero como comprimido y parece que el comportamiento en linux (y en el resto de sistemas normales, hasta ahora) libz se encarga de abrir el fichero en modo normal si no detecta que sea uno comprimido.
No es el caso en la Wii, donde parece que libz falla en caso de que el fichero no esté comprimido. No sé si es un bug de la librería o qué, pero símplemente cambiando el modo de apertura a "rb0" ¡parece que las fuentes ya van como una moto!.

¿Cómo lo ves, Splinter?. ¿Debería ser un "rb0" ahí? ¿o pongo un pequeño patch al fuente para la Wii?
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 22, 2011, 11:52:26 PM
voy a revisarlo... pero puede que sea lo mismo que me pasa en dingux que no veo los fonts...

quizas en psp tambien pasa.

lo raro es que levante los fpg que son comprimidos... lo bueno tambien seria detectar por que la libz no reconoce bien el file.
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 23, 2011, 12:00:31 AM
mmm... raro...

acabo de ver el codigo... si existe '0' entonces no se usa zlib... por ende esta mal no usarlo... la cosa es que por lo visto el archivo no es gzip, pero el gzip lo reconoce como tal, y no como RAW.

fijate si podes buscar algo por ese lado, por que la libz lo reconoce como comprimido cuando no lo es.
Title: Re: Bug de endianess en load_fnt()
Post by: josebita on February 23, 2011, 12:11:07 AM
A lo que me refiero es que estás asumiendo el comportamiento -documentado- que tiene libz en linux: si el fichero es un gzip, lo abro como tal. Si no lo es, lo abro como un fichero normal.
Pero eso parece no funcionar bien en sistemas embebidos. No sé si será cosa de un bug en la libz que se distribuye para Wii pero más bien me parece que la han capado.
Es decir, que en linux/win/osx... esa línea abrirá el fnt tanto en caso de que sea comprimido como en caso de que no lo sea, pero en la Wii sólo es capaz de abrir la fuente si el fichero es realmente comprimido.

Revisaré el código de la libz que distribuyen para la wii para intentar averiguar si es un bug o un comportamiento deliberado y actuar en consecuencia.
Title: Re: Bug de endianess en load_fnt()
Post by: SplinterGU on February 23, 2011, 12:15:16 AM
cuidado... no es asumir, es lo esperado, asi esta documentado...

si el funcionamiento oficial de la lib es abrirlo en RAW cuando no es comprimido, y en una plataforma no lo hace, es un bug.

EDIT: perdon, es al revez, si no esta comprimido deberia fallar... y retornar 0, la open.
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on February 23, 2011, 12:18:17 AM
A eso me refiero, que está documentado. Mañana intentaré averiguar si a todas las libz las han creado iguales o cada una es de su padre y de su madre.
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on February 23, 2011, 12:25:56 AM
voy de nuevo para corregirme nuevamente...

la libz dice, que si el archivo no esta comprimido, lo intenta abrir sin compresion, en dicho caso, si la apertura tiene exito, las operaciones de lectura deberian trabajar sin compresion... por algun motivo, quizas no lo este haciendo bien, o quizas si lo este haciendo bien, pero le falten hacer algunos arranges de datos de cabecera/offsets/etc dentro de la libz, y por eso lee en cualquier lado, ya que por lo que pareciera, los bytes que devuelven, tienen pinta de ser parte de la data del font, pero no del lugar apropiado.
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on February 23, 2011, 12:30:09 AM
En cualquier caso, creo que voy a dejar el código tal y como está y poner como "recomendación" que los fnt han de ir comprimidos. Es una recomendación un poco nazi, porque si no se hace no se cargan las fnt, pero es lo que hay.
Me imagino que casi no tener sistema operativo por debajo es lo que tiene :)
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on February 23, 2011, 01:09:34 AM
la zlib de wii es la lib oficial de zlib? porque no compilas los fuentes oficiales de la zlib y probas?
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on February 23, 2011, 02:06:48 AM
creo que es un tema de byteorder en la zlib.
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on February 23, 2011, 02:23:22 AM
joseba, agregue al codigo la posibilidad de compilarlo sin soporte de comprimidos zlib.

te sugiero que por ahora, deshabilites en la version wii el soporte de zlib, con lo que solo se podra usar en esa version archivos sin comprimir y tambien mochila (si el problema es la zlib, la mochila deberia funcionar perfectamente)

para deshabilitar, agrega el siguiente define en los CFLAGS de la compilacion NO_ZLIB, o donde gustes.
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on February 23, 2011, 10:50:20 AM
OK, gracias. Voy a sincronizar el código y voy a escribir un pequeño script para windows y linux que se encargue de descomprimir los recursos del juegos (FPGs, FNTs, MAPs...) en caso de que lo estén para que los usuarios puedan hacerlo facilmente.
Title: Re: Bug en load_fnt() en la Wii
Post by: Drumpi on February 23, 2011, 01:49:38 PM
Te voy a ahorrar parte del trabajo: tengo este código por culpa de las limitaciones del FPGEdit antiguo :D Sólo habría que añadir los argumentos de entrada y control de errores de los mismos, tan portable como Bennu ;)

[code language="bennu"]program des_zlib;

import "mod_file";

global
    byte b_dato;
    int source, destino;

begin
    source=fopen("test.fpg",o_zread);
    destino=fopen("test_unzip.fpg",o_write);
    while (feof(source)==0)
        fread(source,b_dato);
        fwrite(destino,b_dato);
    end
    fclose(source);
    fclose(destino);
end[/code]

No es mucho, pero bueno, algo tendre que hacer para ayudar ^^U
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on February 23, 2011, 02:45:33 PM
Quote from: Drumpi on February 23, 2011, 01:49:38 PM
Te voy a ahorrar parte del trabajo: tengo este código por culpa de las limitaciones del FPGEdit antiguo :D Sólo habría que añadir los argumentos de entrada y control de errores de los mismos, tan portable como Bennu ;)

[code language="bennu"]program des_zlib;

import "mod_file";

global
    byte b_dato;
    int source, destino;

begin
    source=fopen("test.fpg",o_zread);
    destino=fopen("test_unzip.fpg",o_write);
    while (feof(source)==0)
        fread(source,b_dato);
        fwrite(destino,b_dato);
    end
    fclose(source);
    fclose(destino);
end[/code]

No es mucho, pero bueno, algo tendre que hacer para ayudar ^^U

jejeje, muy buena idea drumpi, no se me habia ocurrido.

gracias, y karma!

PD: Con una pequeña modificacion se puede hacer que recorra todo el directorio/directorios y salve todo en otra carpeta.
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on February 23, 2011, 05:43:54 PM
Quote from: Drumpi on February 23, 2011, 01:49:38 PM
Te voy a ahorrar parte del trabajo: tengo este código por culpa de las limitaciones del FPGEdit antiguo :D Sólo habría que añadir los argumentos de entrada y control de errores de los mismos, tan portable como Bennu ;)

[code language="bennu"]program des_zlib;

import "mod_file";

global
    byte b_dato;
    int source, destino;

begin
    source=fopen("test.fpg",o_zread);
    destino=fopen("test_unzip.fpg",o_write);
    while (feof(source)==0)
        fread(source,b_dato);
        fwrite(destino,b_dato);
    end
    fclose(source);
    fclose(destino);
end[/code]

No es mucho, pero bueno, algo tendre que hacer para ayudar ^^U
¡Muchas gracias!
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on March 03, 2011, 01:31:06 AM
Sólo por comentar... Al final lo he hecho justamente al revés: he puesto como requisito que todos los recursos vayan gzippeados.
Lo he hecho así porque aunque quitara la libz de Bennu, tenía que seguir linkando contra ella para libpng y además haber exigido que todo estuviera descomprimido me da la impresión de que sería complicarle la vida a la gente, porque todos los recursos que genera Bennu ahora (FPG y MAP, sobre todo) están comprimidos y habría que hacer que el usuario descomprimiera todos uno a uno...
Suficiente le pido ya con resamplear todo el audio y compilar en la Wii como para encima exigirle que retoque todos los FPGs a mano (que pueden ser muchos).

Sólo lo comento para que conste, la verdad es que funciona muy bien ahora :)
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on March 03, 2011, 02:30:48 AM
joseba, no estoy de acuerdo con lo que has hecho, ya que esto te va a hacer que funcionen los recursos, pero no va a funcionar ningun load de vars/structuras, ni tampoco lectura de archivos de texto o raw.

creo que es un error...
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on March 03, 2011, 11:17:52 PM
Bueno, la carga de estructuras con load y save parece ir sin problemas, al menos en las pruebas que he hecho con el firewhip.
El resto de juegos que he probado parecen ir muy bien también. Voy a intentar averiguar cuál es el problema porque creo recordar que los FPG sin compresión sí se abren bien...
Title: Re: Bug en load_fnt() en la Wii
Post by: SplinterGU on March 03, 2011, 11:48:01 PM
quizas dependa de cierta combinacion de datos
Title: Re: Bug en load_fnt() en la Wii
Post by: josebita on March 04, 2011, 12:02:40 AM
Voy a intentar mirarlo con cariño en cuanto saque un rato, porque la verdad es que me tiene bastante extrañado.