miércoles, 13 de abril de 2011

Aprendiendo C: Satuxconv (III)

Ya tenemos claro los pasos que, de momento, tiene que hacer nuestro programa. A saber:
  • Abrir el fichero en modo sólo lectura.
  • Acceder al byte número 32 y leer 16 bytes.
  • Mostrar, de forma continua, el contenido de esos bytes.
  • Repetir el proceso con el resto de campos que queremos mostrar.
En el manual que comentaba en la primera entrada de esta serie, podemos encontrar todo lo necesario para poder hacer esto sin más problemas.

Código:

/* Satuxconv */

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int i; /* contador */
int j; /* contador 2 */
int buffer; /* Buffer de datos */
FILE* fichero; /*Fichero a abrir */

void mostrar (int pos, int maximo)
{
for (i=1; i<=maximo; i++)
{
j = (pos + i);
fseek(fichero, j, SEEK_SET);
fread(&buffer, 1, 1, fichero);
printf("%c", (char)buffer);
}
}

main (int argc, char *argv[])
{
int fecha[8]; /*Almacena la fecha*/
int regiona[3]; /*Region del juego*/

/*Comprobar parámetros y abrir fichero*/
printf("\nSatuxconv\n");
if (argc < 2)
{
printf("Uso: satuxconv imagen.bin");
printf("\nActualmente se soportan imagenes BIN\n\n");
exit(0);
}

fichero=fopen(argv[1], "rb");

printf("\nDatos de la imagen\n");
printf("------------------\n\n");

/*Obteniendo el titulo*/
printf("Título: ");
mostrar(111,27);

/*Obteniendo el desarrollador*/
printf("\nDesarrollador: ");
mostrar(31, 16);

/*Obteniendo el producto*/
printf("\nProducto: ");
mostrar(47,7);

/*Obteniendo la version*/
printf("\nVersión: ");
mostrar(57,6);

/*Obteniendo la fecha*/
printf("\nFecha: ");
for (i=1; i<=8; i++)
{
j = (63 + i);
fseek(fichero, j, SEEK_SET);
fread(&fecha[i], 1, 1, fichero);
}
printf("%c%c/%c%c/%c%c%c%c\n", (char)fecha[7],(char)fecha[8], (char)fecha[5], (char)fecha[6], (char)fecha[1], (char)fecha[2], (char)fecha[3], (char)fecha[4]);

/*Obteniendo regiones*/
for (i=1; i<=3; i++)
{
j= 79 + i;
fseek(fichero, j, SEEK_SET);
fread(&regiona[i], 1, 1, fichero);
}

/*Mostrar regiones*/
printf("\nRegión(es) del juego:\n");
for (i=1; i<=3; i++)
{
printf(" %c", (char)regiona[i]);
if ((char)regiona[i] == 'T')
printf(" - (Asia - NTSC)\n");
if ((char)regiona[i] == 'E')
printf(" - (Europa)\n");
if ((char)regiona[i] == 'U')
printf(" - (América del Norte)\n");
if ((char)regiona[i] == 'J')
printf(" - (Japón)\n");
if ((char)regiona[i] == 'B')
printf(" - (Centro/SudAmérica NTSC)\n");
if ((char)regiona[i] == 'K')
printf(" - (Corea)\n");
if ((char)regiona[i] == 'A')
printf(" - (Asia Este PAL)\n");
if ((char)regiona[i] == 'L')
printf(" - (Centro/SudAmérica PAL)\n");
}

/*Cerrar fichero*/
fclose(fichero);
}
El editor de Blogspot es un poco caprichoso y ha alineado a la izquierda todo el código, dejándolo sin tabuladores, y algún posible error, lo siento !

Se ha creado una función llamada "mostrar" que se encarga de leer los bytes en cada uno de los pasos. Gracias a esto la cantidad de código se reduce considerablemente.

Compilamos el código fuente y ejecutamos:

./satuxconv Castlevania.bin

Satuxconv 0.05

Datos de la imagen
------------------

Título: DRACULA-X
Desarrollador: SEGA TP T-95
Producto: T-9527G
Versión: V1.400
Fecha: 27/04/1998

Región(es) del juego:
E - (Europa)

Funciona ! En la siguiente entrada pasaremos al modo escritura y cambiaremos la región del juego por la que nosotros queramos.

jueves, 7 de abril de 2011

Aprendiendo C: Satuxconv (II)

Primeros pasos

Ya tenemos claro cual es la finalidad del programa: que abra un archivo de imagen de CD, busque el código de región y pregunte al usuario cual desea establecer (o dejarlo sin modificar). Preguntas varias me asaltan: Dónde está el dato ? Cómo se cuál es ? Como accedo a él ? Respuestas: Pues ni idea, oiga. Toca investigar un poco.

Las imágenes de CDs para esta consola vienen en tres formatos (que yo conozca, pueden haber más): ISO, BIN y MDF. En todos los casos son imágenes del disco compacto, hecho con varias herramientas.

Conociendo el interior del fichero

Para empezar elegimos un juego concreto: Castlevania Symphony of the Night, un juego para Sega Saturn de Konami, que no salió de Japón. Podemos encontrar una pista de audio y la imagen del CD en formato BIN. Tomamos el fichero (con un tamaño de 460 Mb.) y utilizamos una herramienta de edición de ficheros "en bruto", en el caso de KDE tenemos Okteta. Veamos que tiene esto dentro...


A la izquierda los datos en formato hexadecimal, a la derecha en caracteres ASCII, más fácil de comprender para nosotros.

Podemos ver datos interesantes: dos códigos por ahora desconocidos (SEGA TP T-95 y T9527G), la versión del juego (V1.400). la fecha (27 de abril de 1998, en formato añomesdia), tipo de CD (CD-1/1), dos caracteres (dos J) y el título del juego (Dracula X).

Esas dos J son dos códigos de región, el primero corresponde al juego en sí, el segundo es para los periféricos y vamos a ignorar (tenéis mas información de este código aquí).

Para resolver la duda de los códigos que no conocemos podemos ver esta captura del SRP donde veremos como SEGA TP T-95 es el desarrollador del juego (Konami) y T9527G es el número del producto.

Con la misma herramienta, en este caso Okteta, vamos a ver cual es la posición de todos estos datos para que el programa pueda leerlos y escribirlos si fuera menester. Una forma simple (y algo chusca) es contar los caracteres hasta la posición deseada. Siendo el primer carácter el 0 tenemos que:
  • El desarrollador empieza en el byte 32.
  • El número del producto empieza en el byte 48.
  • La versión empieza en el byte 58.
  • La fecha empieza en el byte 64.
  • El código de región está en el byte 80.
  • El título empieza en el byte 112.
Con estos datos ya podemos empezar el parcheador. Una primera versión del programa abrirá el archivo en sólo lectura (para evitar destrozos accidentales) y visualizará todos estos datos. Si funciona correctamente se podrá pasar a la siguiente fase, poder cambiar el código de región.

En la siguiente entrada vamos a por la primera versión.

miércoles, 6 de abril de 2011

Aprendiendo C: Satuxconv (I)

Mis conocimientos en lenguajes de programación son muy escasos. Con mi ordenador MSX aprendí Basic, a los 13 años de edad. Pascal y Cobol se añadieron a la lista durante el segundo grado de FP. La lista se detuvo aquí y me centré en sistemas operativos, redes, etc.

Hoy, 14 años más tarde, me he puesto manos a la obra para aprender nuevos lenguajes y el elegido ha sido, por su cercanía a los sistemas *nix, C. Con miras a C++ y, finalmente, QT.

Vuelta al aprendizaje

Encontré un manual de iniciación bastante bueno en la web de Nacho Cabanes. Y a ponerse a ello: con paciencia ir asimilando nuevas órdenes y algunas nuevas formas de hacer las cosas. Algunos viejos conceptos de los lenguajes que conocía me sirvieron para avanzar un poco más rápido, ya que eran muy similares. Pude comprobar que era cierta la frase aquella de (más o menos decía así): aprender cualquier lenguaje te da una buena base para aprender otros lenguajes de programación.

Una vez terminado el curso, como seguir ? He optado por hacer un programa, no muy complicado pero que contenga pequeños retos que, al empezar, no sepa como afrontar. Ayudándome de Internet puedo ir resolviendo esos problemas y, en el fondo es lo que interesa, aprender y ganar experiencia.

Qué programa hacer ? Debería ser un programa que no existiera en GNU/Linux y me gustaría utilizar... pensemos...

Satuxconv: Parcheador de imágenes ISO de Sega Saturn

Sega Saturn fue la consola de 32 bits de Sega. Fue la segundona en la batalla ganada por Sony con su Playstation.

Un servidor pudo hacerse con una Saturn de segunda mano por 5000 de las antiguas pesetas (1998, aproximadamente) junto con un par de juegos. Por desgracia para esta plataforma, muchos juegos buenos no salieron de Japón, así que la única manera de poder disfrutarlos era descargarlos de Internet y grabarlos en CD.

Pero esto no era suficiente, la consola lleva una protección regional. Se dividió el mundo en 8 partes y tanto la consola como los juegos llevan uno (o dos, como máximo) regiones en su código. Si no coinciden, la consola se niega a ejecutar el juego. Esta táctica se sigue utilizando hoy en día en las consolas actuales.

Pues bien, existía en aquel tiempo un programa para MsDos, llamado Satconv, que permitía cambiar la imágen ISO de región, a voluntad. Si el juego era japonés, podía cambiarle la región a Europa y jugarlo sin problemas en una Saturn española. Gracias a dicho programa pude disfrutar de auténticas joyas para esta plataforma.

Hoy en día existen programas gráficos que hacen esa misma función, como SRP. Pero en Linux creo que no hay nada parecido. Así nació, mi primer reto: hacer un programa parecido al Satconv pero para GNU/Linux, utilizando el lenguaje de programación C.

Sabía mostrar mensajes por pantalla, obtener ordenes del usuario y abrir ficheros. Pero no tenía ni idea de como "parchear" imágenes ISO y/o BIN. Es más, no tenía ni idea de como abrir dichos ficheros. Toca investigar y aprender :)

En el siguiente post, empezamos a entrar en materia.