miércoles, 19 de octubre de 2011

Tux Adventure en acción

Este es un video que hice poco antes de terminar la versión 0.1, sólo se diferencia en algunos sonidos y sprites que se añadieron posteriormente.



Y aquí algún boceto de lo que puede ser la pantalla de juego de la v 0.2, eliminando la franja superior del marcador y distribuyendo sus datos por la pantalla. Que os parece ?

martes, 18 de octubre de 2011

Tux Adventure 0.1

Acabo de subir el código fuente de la versión 0.1 a la página del proyecto en Sourceforge. El juego dispone de la funcionalidad básica que esperaba alcanzar. Para compilar el programa hay que tener instalado el GCC y las librerias SDL, SDL-ttf, SDL-image y SDL-mixer. Se ejecuta esta orden:

gcc -o adventure src/adventure.c `sdl-config --cflags --libs` -lSDL_image -lSDL_mixer -lSDL_ttf

Y ya tenemos, no se debería reportar ningún error durante la compilación, el binario listo para ejecutar

A partir de ahora será la base para la versión 0.2, en la que espero empezar a adecentar un poco el aspecto general.

Mirando atrás

43 Kb pesa el código fuente, 1675 líneas de C + SDL, 33 archivos gráficos y 13 archivos sonoros.

Ha sido unos 2/3 meses interesantes donde la pregunta que más me he hecho ha sido "y esto como lo hago en código?" y muchos minutos de darle vueltas y más vueltas. Mucho rato mirando el código en busca de "porque no funciona ?" estando el motivo delante de mis narices. Muchas compilaciones y pruebas. He rejugado la fase decenas de veces, casi me la se de memoria.

El código resultante seguramente no sea muy elegante. Los que sepan de programación puede que vean auténticas burradas, pero la principal razón de ser de este programa es ir aprendiendo programación desde prácticamente 0. Y ha cumplido su función con creces, he aprendido mucho de esta experiencia.

A por la 0.2

La parte gráfica y sonora son las partes que espero mejorar en esta versión. Que el juego se gane la palabra "remake" y no "demake" :D

Hay que aprender mucho sobre hacer gráficos y seguir buscando una buena fuente de sonidos y músicas. Dejar de un lado el código fuente y hacer muchas horas con el Gimp y el Audacity.

Como siempre, cualquier colaboración será bien recibida :D

viernes, 23 de septiembre de 2011

Tux Adventure - un remake de Antartic Adventure (o demake) ? :D

Antartic Adventure, un juego desarrollado por Konami en 1985 para los sistemas MSX y NES (entre otros). Un pingüino corriendo por la Antártida para alcanzar la meta (una estación científica) antes que el cronómetro llegue a 0.

Queriendo mejorar mis pobres conocimientos del lenguaje C y experimentar todo el proceso de desarrollar un videojuego, he empezado este proyecto para crear, en mi tiempo libre, un remake de este juego utilizando las librerías SDL. Mi intención es seguir las líneas del juego original, añadiendo algunos detalles propios.

Mis habilidades como diseñador gráfico son muy pobres. Así que la primera versión (0.1) está dirigida a que el código funcione correctamente (movimiento de objetos, eventos, colisiones, velocidad, etc.) y contendrá la primera fase. En este momento los gráficos no son importantes así que son sencillos, mientras iré aprendiendo del fantástico mundo del PixelArt :)

En las siguiente versiones (0.2, 0.3, etc.) el resto de fases se irán añadiendo y los gráficos serán mejorados.

En la sección de descargas del proyecto podrás encontrar el estado actual del programa (has de tener el compilador GCC y las librerias SDL instaladas, además de compilar el programa): podrás ver la pantalla de inicio, y la primera fase con algunos objetos puestos al azar para probar el código. Tux, el protagonista, también está allí pero solo puede moverse a la derecha o a la izquierda... el salto es lo próximo a añadir ;)

Cualquiera que quiera colaborar es bienvenido, los inicios son los momentos más difíciles. Pero estoy seguro que con ayuda el programa progresará más rápidamente y los resultados serán mejores.

Saludos !

martes, 10 de mayo de 2011

Aprendiendo C: Satuxconv (IV)

El programa ya lee imágenes de CD en formato BIN, falta añadir soporte a las imágenes en formato ISO (el formato restante, MDF, es igual que BIN). De nuevo, mediante Okteta abrimos un archivo de este tipo para buscar las diferencias.

Nos encontramos que el título del juego se encuentra en la posición 95, 16 posiciones menos respecto a la imagen en formato BIN o MDF. Este patrón se repite en el resto de los campos.

La solución es fácil:
  • Comprobar si el archivo a abrir es una imagen ISO. Comprobaremos la extensiones del archivo que ha indicado el usuario.
  • Si es una ISO se activa una variable.
  • Al buscar un campo (por ejemplo la fecha) si la variable está activa se restará 16 caracteres a la posición de búsqueda.
Para comprobar si la extensión del fichero indicado es "iso" basta con este código:
if (strstr(argv[1], ".iso") != NULL)
imgiso = 1;
Y cada vez que comprobamos un campo añadimos esto:

void mostrar (int pos, int maximo){
for (i=1; i<=maximo; i++)
{
if (imgiso==1)
j = (pos + i) - 16;
else
j = (pos + i);
fseek(fichero, j, SEEK_SET);
fread(&buffer, 1, 1, fichero);
printf("%c", (char)buffer);
}
}
Sabiendo esto nos queda este programa:
/* 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 */
int imgiso = 0; /* flag */

void mostrar (int pos, int maximo){
for (i=1; i<=maximo; i++)
{
if (imgiso==1)
j = (pos + i) - 16;
else
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*/
if (argc < 2)
{
printf("Uso: satuxconv imagen.bin");
printf("\nActualmente se soportan imagenes BIN, ISO y MDF\n\n");
exit(0);
}

fichero=fopen(argv[1], "rb");
if (strstr(argv[1], ".iso") != NULL)
imgiso = 1;

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++)
{
if (imgiso==1)
j = (63 + i) - 16;
else
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++)
{
if (imgiso==1)
j = (79 + i) - 16;
else
j= 79 + i;
fseek(fichero, j, SEEK_SET);
fread(&regiona[i], 1, 1, fichero);

/*Obteniendo regiones*/
for (i=1; i<=3; i++)
{
if (imgiso==1)
j = (79 + i) - 16;
else
j= 79 + i;
fseek(fichero, j, SEEK_SET);
fread(&regiona[i], 1, 1, fichero);
}
/* fseek(fichero, 96, SEEK_SET);
fread(&regionb, 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);
}
Con esto nuestro programa ya puede leer tres tipos de imágenes de disco: BIN, MDF (MDF tiene el mismo formato que BIN) e ISO. Sólo queda acceder en modo escritura al fichero y cambiar la región por la deseada.

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.