Romxhacking Romxhacking
- Nasío pa'jakear -
 
 F.A.Q.F.A.Q.   BuscarBuscar   Lista de MiembrosLista de Miembros   Grupos de UsuariosGrupos de Usuarios   RegístreseRegístrese 
 PerfilPerfil   Identifíquese para revisar sus mensajesIdentifíquese para revisar sus mensajes   ConectarseConectarse 


Menú principal
Portal
Foros
F.A.Q.
Buscar
Lista de miembros
Grupos de usuarios
Perfil

Usuario
Nombre de Usuario:

Contraseña:

 Recordarme



He olvidado mi contraseña

¿Aún no tiene su cuenta?
Puede registrarse Aquí, es GRATIS.


Anuncio del administrador
No pretendemos solucionar todos los problemas ni ser referencia de nada, simplemente nos reunimos aquí para charlar de nuestras cosas.
NO SE RESPONDERÁ A NADA POR PRIVADO, QUE EL FORO ESTÁ PARA ALGO

Ayuda Chocobo Dungeon 2 [Fuente]
Ir a página Anterior  1, 2
 
Publicar Nuevo Tema   Responder al Tema    Romxhacking -> Dudas y Preguntas
Ver tema anterior :: Ver siguiente tema  
Autor Mensaje
CUE
Administrador
Administrador


Sexo: Sexo:Hombre
Registrado: 24 Jan 2011
Mensajes: 5435
Estado: Offline
MensajePublicado: Wed Jun 15, 2011 6:44 pm    Título del mensaje: Responder citando

Primero, y con el único propósito de ocupar espacio para que parezca que estamos haciendo algo de la leche y no sólo las 4 líneas necesarias, hacemos unas deficiniones.

Sabemos el nombre del fichero y dónde comienzan los datos de la fuente:
Código:
#define FILENAME "ALLBIN.BIN"
#define POSITION 0xA40000

El número de caracteres de la fuente, así como la altura y anchura de los mismos se debería sacar de los datos, pero como son siempre los mismos nos lo saltamos y lo hacemos a pelo:
Código:
#define NCHARS   0x017A
#define HEIGHT   0x0C
#define WIDTH    0x0C

Sabemos también que hay una cabecera de 72 bytes, correspondientes a 4 bytes, 2 paletas de 16 colores de 16 bits y 4 bytes con el número de caracteres. También sabemos que cada carácter va precedido de 12 bytes con información para situarlo en la VRAM:
Código:
#define OFFSET   72 // 4 + 2*(16*2) + 4
#define SKIP     12

Ahora vamos a definir tamaños. Hacer lecturas byte a byte como haces es muy lento, y, como cualquier fuente no es muy grande, vamos a trabajar con la memoria, así que cargaremos todo en la misma. Como cada carácter lleva 2 pixeles sabemos que los datos reales del carácter serán HEIGHT*WIDTH/2, a los que hay que sumar los 12 bytes de información. Eso para cada carácter. Además hay que sumar los 72 bytes iniciales. Con eso ya tenemos el tamaño real que ocupa la fuente en el fichero:
Código:
#define FILESIZE (NCHARS * (SKIP + HEIGHT * WIDTH / 2) + OFFSET)

Cada una de las semifuentes se forma cogiendo 6 bytes originales, en grupos de 2, que nos da 3 bytes para cada una de las fuentes. Como queremos que el número de pixeles sea múltiplo de 8 para poder verlo con el Tile Molester, eso quiere decir que debemos añadir 4 pixeles, justo los que caben en un byte. O sea, que hay que añadir un byte extra a esos 3. Así que ya sabemos que por cada 6 bytes de datos debemos generar 4, por lo que el tamaño de cada semifuente será (HEIGHT*WIDTH/2)*4/6:
Código:
#define FONTSIZE (NCHARS * HEIGHT * WIDTH / 3) // H*W/2 * 4/6

Y después de todo este rollo, que podíamos habernos saltado, pero así queda mucho más 'potito', vamos a lo nuestro.

Lo primero es crearnos 3 tablas en memoria. Como en este caso son pequeñas, pasamos de hacerlas dinámicas y así evitamos tener que crearlas y liberarlas al final. Las 3 serán de tipo char (caracteres, bytes o como quiera cada uno llamarlas):
Código:
char buffer[FILESIZE], font1[FONTSIZE], font2[FONTSIZE];

Ahora vamos a leer los datos en memoria. En los lenguajes .NET creo recordar que para posicionar un fichero se usaba la instrucción Position.Set, que es lo que te faltaba a ti, pero yo paso de NETs y lo hago de la forma clásica, que ocupa mucho menos, y que después cada uno lo haga a su manera:
Código:
FILE *fp = fopen(FILENAME, "rb");
fseek(fp, POSITION, SEEK_SET);
fread(buffer, sizeof(char), FILESIZE, fp);
fclose(fp);
Ya está. Con 4 míseras líneas ya tenemos los datos originales en memoria y no nos hemos despeinado.

Ahora, y para usar C de verdad, vamos a utilizar punteros para apuntar a cada una de las tablas:
Código:
char *pb = buffer + OFFSET; // origen de los datos
char *p1 = font1; // posición 0 de la fuente 1
char *p2 = font2; // posición 0 de la fuente 2


Y ya sólo nos queda el proceso, que es el mismo para carácter, así que a usar unos bucles, como mandan los cánones. Cada carácter tiene unas filas, y cada fila un ancho. Ya sabemos que antes de tomar los datos hay que saltar los bytes iniciales, y que hay 2 pixeles por cada byte, siendo necesarios 3 grupos de 2 bytes para completar cada fila (WIDTH/4), y al final siempre hay que añadir un byte más:
Código:
for (int c = NCHARS; c; c--) {
  pb += SKIP;
  for (int h = HEIGHT; h; h--) {
    for (int w = WIDTH / 4; w; w--) {
      // aquí va el meollo
    }
    *p1++ = *p2++ = 0xAA; // color 10.10.10.10 en binario
  }
}
NOTA: En vez de añadir un cero patatero, añado 0xAA para que se distinga mejor el carácter resultante. En realidad debería ser 0x55, pues 01 es el color usado para la transparencia, pero a mí me gusta más así.

Ahora vamos a ver cómo separar los datos. Ya hemos visto que partiendo de 6 bytes obtenemos dos series de 3 bytes:
Código:
buffer |  abABcdCD efEFghGH  |  ijIJklKL mnMNopOP  |  qrQRstST uvUVwxWX  |
       | abAB-cdCD efEF-ghGH | ijIJ-klKL mnMN-opOP | qrQR-stST uvUV-wxWX |
       | cdCD-abAB ghGH-efEF | klKL-ijIJ opOP-mnMN | stST-qrQR wxWX-uvUV |
font1  |     cd-ab-gh-ef     |     kl-ij-op-mn     |     st-qr-wx-uv     |
font2  |     CD-AB-GH-EF     |     KL-IJ-OP-MN     |     ST-QR-WX-UV     |

Vamos a hacerlo para los dos primeros bytes y el resto es igual. Con 'abABcdCD' y 'efEFghGH' sacamos 'cdabghef' para la fuente 1 y 'CDABGHEF' para la fuente 2. No hay que olvidar que inicialmente tenemos 2 valores de 4bpp y de cada uno de ellos salen 2 valores de 2bpp, y hay que tener en cuenta el 'reverse', que ya está explicado en un post anterior:
Código:
V1 = abABcdCD
V2 = efEFghGH

pixel ab: ab------ = V1 & 0xC0 (11000000 en binario)
pixel AB: --AB---- = V1 & 0x30 (00110000 en binario)
pixel cd: ----cd-- = V1 & 0x0C (00001100 en binario)
pixel CD: ------CD = V1 & 0x03 (00000011 en binario)
pixel ef: ef------ = V2 & 0xC0 (11000000 en binario)
pixel EF: --EF---- = V2 & 0x30 (00110000 en binario)
pixel gh: ----gh-- = V2 & 0x0C (00001100 en binario)
pixel GH: ------GH = V2 & 0x03 (00000011 en binario)

Ahora hay que pasar esos valores a los nuevos de la fuente, teniendo en cuenta que tenemos que desplazar algunos de ellos varios bits. Por ejemplo, 'ab' debemos deplazarlo 2 bits a la derecha para situarlo en su posición final, pues originalmente ocupa los bits 7-6 y debemos ponerlo en los bits 5-4:
Código:
Para fuente 1: (V1 & 0x30) | ((V1 & 0x03) << 6) | ((V2 & 0x30) >> 4) | ((V2 & 0x03) << 2)
Para fuente 2: ((V1 & 0xC0) >> 2) | ((V1 & 0x0C) << 4) | ((V2 & 0xC0) >> 6) | (V2 & 0x0C)

Una vez hecho todo eso, ya sólo queda grabar las 2 fuentes, cada una en un fichero:
Código:
fp = fopen("fnt1.raw", "wb"); fwrite(font1, sizeof(char), FONTSIZE, fp); fclose(fp);
fp = fopen("fnt2.raw", "wb"); fwrite(font2, sizeof(char), FONTSIZE, fp); fclose(fp);

Y no hay mayor misterio.

Ahora sólo queda modificar los dos ficheros resultantes y hacer el proceso inverso, es decir, coger un byte de cada fuente para regenerar los dos byte iniciales. Pero eso es otra historia que debe ser contada en otra ocasión, aunque no por mí.

Todo junto, para que se vea a simple vista lo poco que ocupa, listo para compilar con cualquier compilador de C clásico:
Código:
#include <stdio.h>

#define FILENAME "ALLBIN.BIN"
#define POSITION 0xA40000
#define OFFSET   72 // 4 + 2*(16*2) + 4
#define NCHARS   0x017A
#define HEIGHT   0x0C
#define WIDTH    0x0C
#define SKIP     12
#define FILESIZE (NCHARS * (SKIP + HEIGHT * WIDTH / 2) + OFFSET)
#define FONTSIZE (NCHARS * HEIGHT * WIDTH / 3) // H*W/2 * 4/6

int main(void) {
  char buffer[FILESIZE], font1[FONTSIZE], font2[FONTSIZE];

  FILE *fp = fopen(FILENAME, "rb");
  fseek(fp, POSITION, SEEK_SET);
  fread(buffer, sizeof(char), FILESIZE, fp);
  fclose(fp);

  char *pb = buffer + OFFSET; // origen de los datos
  char *p1 = font1; // posición 0 de la fuente 1
  char *p2 = font2; // posición 0 de la fuente 2

  for (int c = NCHARS; c; c--) {
    pb += SKIP;
    for (int h = HEIGHT; h; h--) {
      for (int w = WIDTH / 4; w; w--) {
        char ch1 = *pb++;
        char ch2 = *pb++;
        *p1++ = (ch1 & 0x30) | ((ch1 & 0x03) << 6) | ((ch2 & 0x30) >> 4) | ((ch2 & 0x03) << 2);
        *p2++ = ((ch1 & 0xC0) >> 2) | ((ch1 & 0x0C) << 4) | ((ch2 & 0xC0) >> 6) | (ch2 & 0x0C);
      }
      *p1++ = *p2++ = 0xAA;
    }
  }

  fp = fopen("fnt1.raw", "wb"); fwrite(font1, sizeof(char), FONTSIZE, fp); fclose(fp);
  fp = fopen("fnt2.raw", "wb"); fwrite(font2, sizeof(char), FONTSIZE, fp); fclose(fp);

  return(0);
}
(ahora quitamos los 'defines' y ponemos los valores directamente y se nos queda en nada)
Volver arriba
Ver perfil del usuario Enviar mensaje privado  
tchusami



Sexo: Sexo:Hombre
Registrado: 29 Jan 2011
Edad: 25
Mensajes: 86
Ubicación: Librilla
Estado: Offline
MensajePublicado: Wed Jun 15, 2011 8:55 pm    Título del mensaje: Responder citando

impresionante!! Shocked ojala nos enseñaran a hacer todas estas cosas... no estamos nada mas que con TDAs uff...
Volver arriba
Ver perfil del usuario Enviar mensaje privado [ Oculto ] Visitar sitio web del autor
CUE
Administrador
Administrador


Sexo: Sexo:Hombre
Registrado: 24 Jan 2011
Mensajes: 5435
Estado: Offline
MensajePublicado: Fri Jun 17, 2011 8:29 am    Título del mensaje: Responder citando

Cita:
... ojala nos enseñaran a hacer todas estas cosas...

Cita:
... se entiende todo bastante bien...

Cita:
... yo aprendí a manejar los ficheros un poco distinto, pero totalmente adaptable a como lo ha hecho CUE.


El problema es que hoy día enseñan las cosas de una forma totalmente dependiente del compilador usado y del sistema operativo, sin tener en cuenta nada más. ¿Por qué es así? Pues porque nadie te va a enseñar a programar, lo único que hacen, ya sea en la uni, en una academia, unos manuales, etc., es enseñarte a poner unas instrucciones que se pueden sacar de cualquier libro. Y si es en casos como éste, donde tienes que aplicar cosas que no tienes por qué saber (fuentes solapadas, gráficos 'reverse', 4bpp, 2bpp), pues no hay que contar con que las enseñanzas de ningún profesor nos saquen las castañas del fuego.

Por ejemplo, en este caso hay 2 cosas que no interesan demasiado (bueno, sí, pero no para cómo queremos hacer el proceso):
- las 3 tablas de las fuentes: da igual que se creen de forma estática, como he hecho yo, o de forma dinámica, donde cada uno usará lo que sabe (operador 'new', función 'malloc', etc.), lo único que importa es que sean tablas de caracteres, se llamen bytes, char o como sea
- el tratamiento de ficheros: no importa cómo se lea ni qué funciones se usen, eso es algo totalmente separado del proceso que queremos hacer, aunque eso sí, no es recomendable que leyendo/grabando byte a byte se empleen casi 60.000 accesos al disco duro cuando se puede hacer con 3 (una lectura y dos escrituras)

Al final debe quedar algo como lo puesto: una inicialización, que es lo que va a depender de lo que uses, ya sea C, C++, C# o el primo de C-mosol que se use. Después deberá ir el proceso, totalmente independiente de las funciones propias del compilador que uses y que deberá servir en cualquier situación, independientemente de lo que uses para programar (hablando de C's claro). Al final, al grabar los datos, ya dependerá otra vez de lo que estés usando.

Resumiendo: se crean las tablas como se quiera, se graban como se quiera, pero el proceso a usar para generar las fuentes deberá ser literalmente como lo he puesto, sin tener que tocarlo, a no ser que las tablas se hagan de otra forma, claro.

Claro que aquí también influye la forma de hacer las cosas de cada uno. Yo estoy acostumbrado a hacer los análisis sin saber quién va a programar ni qué lenguaje se va a usar, así que tengo que poner ejemplos que me sirvan en la mayoría de los casos. Y, como en este caso, me basta el maravilloso, y a veces olvidado, bloc de notas del windows para crear los programas, sin necesidad de ningún mega-compilador-chachi-piruli para hacer las cosas.

Y nada más por hoy, que, curiosamente, tengo que ir a explicar cómo hacer unas cosas para que el código sirva para windows y linux.
Volver arriba
Ver perfil del usuario Enviar mensaje privado  
gadesx
Administrador
Administrador


Sexo: Sexo:Hombre
Registrado: 24 Jan 2011
Edad: 28
Mensajes: 1976
Ubicación: El puche
Estado: Offline
MensajePublicado: Thu Jul 28, 2011 6:33 pm    Título del mensaje: Responder citando

Y toda esa historia de arriba puede valer para el 1?

Código:

Chocobo Collection - Happy 10th Anniversary! - Dice de Chocobo [Disc3of3] [J] [SLPS-02523]   
Chocobo no Fushigi Dungeon [Disc1of2] [J] [SLPS-01234]                     
Chocobo no Fushigi Dungeon [Disc2of2] [J] [SLPS-01235]                     
Chocobo no Fushigi Dungeon 2 [Disc1of2] [J] [SLPS-01771]                  
Chocobo no Fushigi Dungeon 2 [Disc2of2] [J] [SLPS-01772]   

_________________
Mi blog y mi droga: http://gadesxscene.blogspot.com/
Volver arriba
Ver perfil del usuario Enviar mensaje privado [ Oculto ] Visitar sitio web del autor MSN Messenger
Mostrar mensajes anteriores:   
Publicar Nuevo Tema   Responder al Tema    Romxhacking -> Dudas y Preguntas Todas las horas están en GMT + 1 Hora
Ir a página Anterior  1, 2
Página 2 de 2

 
Saltar a:  
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

Temas Relacionados
 Temas   Respuestas   Autor   Lecturas   Último Mensaje 
No hay mensajes nuevos CUE es omnipresente 16 Davoker 3538 Wed Jul 12, 2017 6:46 pm
gadesx Ver último mensaje
No hay mensajes nuevos De todo un poco 2 gadesx 1079 Wed Jul 01, 2015 8:14 am
gadesx Ver último mensaje
No hay mensajes nuevos goodsets y todo eso ¿qué traducciones listan? 14 gadesx 5223 Thu Aug 21, 2014 3:58 pm
CUE Ver último mensaje
No hay mensajes nuevos Las herramientas estas que sirven para todo... xd 1 gadesx 1183 Mon Oct 29, 2012 8:41 am
CUE Ver último mensaje
El tema está bloqueado: no pueden editarse ni agregar mensajes. [Para CUE] Sobre un proyecto de edicion del BOF3/4 de PS1 1 Davoker 1130 Sun Nov 13, 2011 9:00 am
CUE Ver último mensaje
 


Crear foro gratis - Powered by phpBB © 2001, 2005 phpBB Group
subRebel style by ktauber