Acerca del formato FNT y los 8 bits

Started by DCelso, July 24, 2009, 01:04:29 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DCelso

Hola SplinterGu,
una preguntilla, he visto que hay dos posibilidades para guardar un fnt en 8 bits, guardando el magic con 'fnt' y usando el "oldchardata"
Y guardando el magic con "fnx",  la versión con  8 bits y usando el "newchardata".
Mi pregunta es. ¿Ambos fnts de 8 bis funcionan en BennuGD?
Es que la primera prueba que he hecho es convertir un "fnt" a un fnx de ocho bits y he creado un ".prg" para probarlo y me devuelve el load_fnt siempre "-1".
Gracias de antemano.
Monstruos Diabólicos

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

splinter_work

en teoria, deberian...

creo que uno es formato div y otro formato fenix

DCelso

Nada, llevo dos dias perdidos dando vueltas a esto, no se me ocurre el motivo de que no funcione en bennu la fuente fnx de 8 bits.
Me he hecho un visor para poder ver exactamente qué datos hay en el fnt y en el fnx para ver si es que está mal el offset o algo y nada, parece estar todo correcto pero bennu siempre me devuelve -1
Te adjunto pruebas para ver si puedes ayudarme a encontrar la falla.
Monstruos Diabólicos

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

DCelso

splinter, he modificado el fntviewer para que muestre también la información de paleta y gamma por si podría estar por ahí el error, pero nada, está todo correcto, en teoría.
Creo que tiene que ser un error de bennu en la lectura de fnx de 8 bits, es la única explicación que encuentro por ahora.
Monstruos Diabólicos

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

SplinterGU

#4
no se como lo estas haciendo, pero el fnx funciona bien... prueba grabar el fnt cargado como fnx y luego cargalo en el test de fnx, y veras como funciona...

voy a describir el formato fnx:

1) cabecera 8 bytes ("fnx\x1A\x0D\x0A\x00" + 1 byte de profundidad de color)
2) si 8bpp -> 768 de paleta + 576 bytes de gamma (se ignora el contenido de la gamma)
3) 1 dword (4 bytes) charset
4) struct chardata[256] (28 * 256 = 7168 bytes)
5) 256 caracteres (nunca mas o menos) que se compone de la data del char o mapa, que es "ancho en bytes" * alto (donde "ancho en bytes es", en 1bpp = 1byte cada 8pixels, 8bpp = 1, en 16bpp = 2, en 32bpp = 4)

eso es el formato, y asi funciona correctamente.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

edite, el texto porque me confundi, pero funciona igual...

de paso al revisar esto, me di cuenta que estoy usando directamente las funciones de gzip, voy a cambiar eso.

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

SplinterGU

q tal fue esto? por favor, manteneme al tanto.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

Oh, sorry.
A ver, te pongo al día y de camino te pregunto otra cosilla.
En principio el problema era que en el chardata yo estaba tratando solo 6 campos, me salté sin querer el campo horizontal_offset (:D), solventado ese problema, he probado a generar fuentes de 1,8,16,24 y 32 bits y a ver.
las de 1 bit no me van, el offset no lo calculo bien, este formato es bastante peculiar y dificil de programar por lo de no ser secuencial :(. Tengo que recontruir el motor de generación de offset que tengo actualmente.
Las de 8 bits van perfectas,
Las de 16 bits los colores fallan, no se porqué motivo, a ver si me puedes aclarar en qué formato se guardan los dos bytes de cada pixel, actualmente he probado con GBR en 565 y no me fué, me salen los colores cambiados, también he probado en RGB 565 y nada.
Las de 24 bits no puedo progarlas porque no funcionan en bennu, el formato es RGB en 888(copiado de las de 32 bits pero sin  el canal alfa)
Las de 32 bist van muy bien excepto por un fallo en el alfa, no cambia y siempre usa 255, esto viendo el motivo, parece ser que no reconoce el color a cambiar el alfa.
Monstruos Diabólicos

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

SplinterGU

bien, ya me parecia raro que en esto tenga errores esa parte de bennu...

en 16 bit... siempre es RGB 565... pero hay unas funciones de conversion raras, que se usan solo en los fonts y en los fpg... pero mas alla de eso, creo que las conversiones estan siendo nulas, ya que convierten de screen a 565, pero screen es 565, asi que no hace nada...

por que no pones la parte del codigo que se encarga de hace esto y lo vemos, como tambien fonts de ejemplos?

el formato 1bit es simple... 1 byte puede contener desde 1 hasta 8 pixels, 1,2,3,4,5,6,7 u 8 de ancho es 1 byte... si tenemos menos de 8 pixels el resto del byte no usado se descarta y no se usa para nada.

32 bits, es lo que dice la informacion del font, no se hace ningun tipo de conversion, asi que estas vos forzando a 255, o en la carga del mapa o char o en la grabacion del font.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

Pues, vamos a ver como lo hago, el código es delphi (pascal)
Ya medio va todo pero regulin regulan.
Los fnts de un bit salen cortados por el final, no entiendo el porqué.
los fnts de 16 bis los colores son cambiados, te adjunto estas dos fuentes y un visor que he hecho para leerlas
Monstruos Diabólicos

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

DCelso

adjunto visor. Si abres con el visor las fuentes de 8 y 32 bits verás los colores originales, si abres la fuente de un bit verás el error de cortado, si abres la de 16 verás el color invertido RGB en vez de GBR. (esto tengo que cambiarlo, ahora mismo es así porque es la forma nativa de 16 bits de delphi) El problema es que al abrir el ejemplo de bennu, los colores de esta fuente son distintos a los de en 8 y 32 bits.
He revisado sendas veces el 16 bits y el 1 bit y no encuentro el fallo.
el código implicado es el siguiente:
Para el caso de un bit, la imagen está guardada en pixel format de 8 bits por pixel, asi que recorro esta imagen byte a byte y si el byte (= pixel) es distinto de 0 inserto un 1 en la variable que uso para construir los bytes del pixel format 1 bit. Cuando tengo ya 8 pixeles leídos o no tengo más que leer en la línea grabo.

    for k := 0 to mybitmap.Height - 1 do     <--- recorre todas las filas
    begin
     pSrc := mybitmap.ScanLine[k];  <-- obtiene los datos de los píxeles de una fila entera

     case fnt_info.version of
       1:
       begin
         insertedBits :=0;
         byteForFPG1 :=0;
         for h :=  0 to fnt_info.chardata[i].Width -1 do begin
          if pSrc[h] <> 0 then begin
             byteForFPG1 := byteForFPG1 OR 1; // bit más alto en 8 bits
          end;
          insertedBits :=  insertedBits +1;
          if  (insertedBits = 8) or (h = 0)  then begin
             while insertedBits <>8 do begin
               byteForFPG1 := byteForFPG1 shl 1;
               insertedBits :=  insertedBits +1;
             end;
            f.Write(byteForFPG1, 1);
             byteForFPG1 :=0;
             insertedBits :=0;
          end else
             byteForFPG1 := byteForFPG1 shl 1;
         end;
       end;
       8:
       begin
           f.Write(pSrc^, fnt_info.chardata[i].Width);
       end;

Para 16 bits ,la imagen internamente está en 16 bits windows/delphi, así que hay que convertirla en 16 bits bennu

       16:
       begin
          for m := 0 to fnt_info.chardata[i].width - 1 do begin
           RGBtoBGR(byte_line[0], byte_line[1],
                    pSrc[(m*2)], pSrc[(m*2) + 1]);
           f.Write(byte_line,  2);
          end
       end;

la función rgbtobgr es por lo que comenté del sistema nativo de 16 bits de windows/delphi.
hace esto:

procedure RGBtoBGR( var bgr0,bgr1: Byte ; rgb0, rgb1 : Byte);
begin
R16 := rgb1 shr 3;
G16 := ((rgb1 and $7) shl 3) + (rgb0 shr 5);  //#00000111
B16 := rgb0 and $1F; //#00011111
num   := (B16 shl 11) + (G16 shl 5) + R16;
bgr0 := num AND $FF;
bgr1 := (num shr 8 )AND $FF;
end;
Monstruos Diabólicos

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

SplinterGU

en el codigo de 1 bit... al final de esto

          end else
             byteForFPG1 := byteForFPG1 shl 1;
         end;

tenes que chequear, si insertedBits > 0, entonces tenes que insertar ese byte... con los bits seteados hasta insertedBits y el resto a 0.

la rotacion deberias hacerla al inicio de cada ciclo del for... y no al final...

mejor deberia quedar asi...


       byteForFPG1 :=0;
       for h :=  0 to fnt_info.chardata[i].Width -1 do begin
          if pSrc[h] <> 0 then begin
             byteForFPG1 := byteForFPG1 OR (1 shl (h and 7));
          end;
          if  (h and 7) = 7 then begin
            f.Write(byteForFPG1, 1);
             byteForFPG1 :=0;
          end
       end;
       if  (h and 7) <> 7 then begin
            f.Write(byteForFPG1, 1);
       end


con respecto a 16 bit, no es BGR, es RGB. Windows no usa un sistema diferente de bennu, asi que si delphi usa el mismo que windows, entonces es el mismo que bennu.
ahora estoy un poco complicado para analizar el tema de los 16bits... cuando tenga un tiempo si no lo resolviste lo reviso mas detenidamente...
saludos.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

gracias, voy a ver que tal, a las dos cosas, aunque si no recuerdo mal ya probé lo de los 16 bits RGB sin buen resultado. Por cierto, eso que comentas de que en 16 bits es RGB es solo para FNTS entonces ¿no?. Porque en el editor FPG 2009 está GBR para fenix con magic "f16" y RGB para cdiv  con magic "c16".
Monstruos Diabólicos

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

DCelso

Mala suerte, no fué ninguna de las dos cosas.
He intentado hacer un pantallazo mostrando los puntos importantes del test.
El de 32 bits, actualmente es un "arreglo de compromiso", lo que hago es insertar la componente alfa a última hora para ello miro el color del pixel y si es sombra inserto el alfa de sombra y si es reborde inserto el alfa de reborde. Lo hize así para tener una primera versión rápida sin tener que tocar mucho el núcleo del fntedit.
El de 1 bit, inserté tu código tal cual, lo hiciste un poco ofuscado, o no tengo tanto nivel para entenderlo :(. Mi algoritmo anterior lo seguí con lapiz y papel y funcionaba perfectamente, yo insertaba el último trozo incompleto cuando llegaba a "h = 0", vale creo que vi el fallo, tengo que cambiarlo por width -1 e irá, :D mientras te lo explicaba ví la luz, voy a probarlo.
El de 16 bits he hecho un mapeo directo de los dos bytes que usa windows y se ve eso que muestro en la pantalla, unos colores inventados totalmente :D.
El de 24 bits me va perfecto, también es mapeo directo de los tres bytes que usa windows, y si lo abro con mi fntviewer se ven todos los caracteres, lástima que no vaya en bennu :(. A mi gusto le faltan dos cosillas en el manejo de imágenes a bennu, una es esta y otra es poder cambiar la paleta de un map por otra, esta técnica es muy buena para hacer por ejemplo dobles de malos con otros colores sin tener que repetir y colorear en un programa externo todos los sprites base.

El de 8 bits FNX también va de lujo, vamos esto era de esperar, si lo hacía antes con el 8bits FNT, solo fue añadir campos nuevos y reajustar los file_offset :D.

Post Data: Si quereis generar fuentes con 32 bits para ya, podría subir una versión castrada solo para este formato.
Monstruos Diabólicos

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

DCelso

JUASJUAS, he visto que pasa tokiski de los ejemplos que pongo, "0 descargas" y uno que tiene 1 descarga es porque me lo bajé yo :D.
Gracias a todos los que os lo bajasteis :D.
No os ofendais, es bromita.
Monstruos Diabólicos

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