Vamos a provocar un poco de inquietud en ti para animarte a programar algo para la consola Neo Geo Pocket. En este ejemplo, te enseñaremos a realizar un Hello World y ver como se muestra posteriormente.
Antes de nada, no se va a explicar como aprender a programar, eso ya es una terea tuya personal, pero si te vas a meter con esto, necesitas saber como se programa en lenguaje C ( no C++ o C# )
¿QUÉ NECESITAMOS PARA PROGRAMAR PARA EMPEZAR?
Todo lo que necesitas lo puedes encontrar en la sección de Herramienta de Desarrollo . Indicar que la compilación de la ROM, en sistemas Windows, solo funciona bajo Windows XP.
- Con el editor de texto simplemente vamos a meter líneas de código que harán algo (programación en C)
- El compilador del Chip TCS900C, nos permitirá coger nuestro código escrito en el notepad y compilarlo para sacar una ROM
- EL framework es un entorno de trabajo desarrollado en C, que nos dan funciones y accesos a la NGPC, métodos como Imprimir por pantalla, insertar sprites, poner un audio, etc.
Una vez esto claro, vamos a configurar el entorno.
Lo primero que vamos a hacer es descargar el Compilador, y lo descomprimimos en C: (puede ser otro directorio pero aconsejo la raiz de un disco que useis). Una vez descomprimido tendremos el siguiente directorio:
Hay varios directorios, pero el principal es el T900, el cual contiene los archivos necesarios para compilar la rom.
Ahora, descargamos el Framework y lo descomprimimos en cualquier directorio que quieras, aunque yo aconsejo ponerlo en C:/ también. Tendremos el siguiente directorio:
De este directorio, los archivos que vamos a utilizar son:
carthdr.h makefile maxidemo.c
PASO 1
El fichero carthdr.h, es el fichero que creará una estructura de cabecera para el cartucho, es decir, este archivo lo que hace es crear una entrada en la rom para que la Pocket lo identifique. Vamos a editarlo, para ello lo arrastramos a el Notepad++ y verémos algo como lo siguiente:
const char Licensed[28] = " LICENSED BY SNK CORPORATION"; const FuncPtr ptr = main; const short CartID = 0;const short System = 0x1000; const char CartTitle[12] = "FRAMEWORK "; const long Reserved[4] = {0,0,0,0};
De aquí, lo que nos interesa es la siguiente linea:
const char CartTitle[12] = "FRAMEWORK ";
Esta línea, lo que hace es indicar el nombre del juego. Podeis darle lo que querais pero no puede pasar de 12 caractéres (const char CartTitle[12]). Por ejemplo, podemos darle como nombre «RTYPE3 «, nótese los espacios para completar 12 carácteres.
Con esto ya tenemos nuestro fichero de cabecera creado, aho podemos guardarlo y ir al siguiente paso.
PASO 2
Ahora abrimos con el notepad el fichero makefile. Este fichero se encargará de indicarle al compilador, que ficheros son los que tiene que coger para compilar, ¿es simple no? AL abrirlo veremos lo siguiente:
.SUFFIXES: .c .asm .rel .abs NAME = MAXIDEMO OBJS = maxidemo.rel library.rel$(NAME).ngp: makefile ngpc.lcf $(OBJS) tulink -la -o $(NAME).abs ngpc.lcf system.lib $(OBJS) tuconv -Fs24 $(NAME).abs s242ngp $(NAME).s24 .c.rel: cc900 -c -O3 $< -o $@ clean: del *.rel del *.abs del *.map del *.s24
En este fichero, fijemonos en lo siguiente:
NAME = MAXIDEMO -> Aqui vamos a cambiar esto por el nombre de nuestro juego (no hace falta que sea de 12 caracteres como en el carthdr.h, simplemente podríamos RTYPE4, ejemplo:
NAME = RTYPE3
Lo siguiente:
OBJS = maxidemo.rel library.rel
Esto lo que va a hacer, es declarar un Array, que contendrá estos dos ficheros, para luego trabajar con ellos. Realmente al empezar por primera vez solo va a existir el library.rel, el maxidemo.rel aún no lo tenemos pero nos es irrelevante.
aqui ahora mismo, no hacemos nada, pero, si en un futuro nuestro fichero de código (que en este caso se llama maxidemo.c) lo renombramos y ponemos que se llama rtype4.c, aquí habrá que ponerse lo siguiente:
OBJS = rtype4.rel library.rel
De resto nada más, grabamos el fichero y a lo siguiente.
PASO 3
Ahora ya lo que queda es meter el código y empezar a programar, así que abrimos el fichero maxidemo.c. Este fichero, para que no os lieis, no se llama maxidemo por que si. Se llama asi porque es una demo que viene con el framework para que mireis como se programa y para que probeis a compilarla, podeis hacerlo si quereis con los pasos que voy dando.
Normalmente, se programa en C o en Ensamblador, yo me decanto por C ya que ensamblador ni idea. La estructura de un fichero de un juego suele tener la siguiente estructura básica:
/* Hello World Rom creada para mostrar un Hello World */ #if 1 // header files #include "ngpc.h" // required #include "carthdr.h" // required #include "library.h" // NGPC routines #include <stdlib.h> // std C routines #include <stdio.h> #include "colors.h" // used for bitmapdemo2 // data files #include "colors.inc" // used for colordemo #include "sample.inc" // used for neodemo #include "sprites.inc" // used for sprdemo #include "fr_tiles.inc" // used for DrawBox #endif #if 1 // global variables u8 rstat; // gets restart status before init routines u8 data[256]; // for flashdemo #endif #endif void main(void) { // Inicio de ejcución del juego. rstat = USR_BOOT; InitNGPC(); while (1) { FillScreen(SCR_1_PLANE, (u16)' ', 0); FillScreen(SCR_2_PLANE, (u16)' ', 0); } } // Fin de rutina Main
Esto es muy simple, lo explico:
Todos las lineas que pone #include, es porque se importan otros ficheros a este con el que trabajamos para poder usarlos. Estos ficheros puden ser, ficheros de sprites, de sonido, de tiles, una libreria de código, etc. Por ejemplo tenemos la línea siguiente:
#include "colors.inc" // used for colordemo
Esta linea, incluye en nuestro código el fichero colors.inc, que tiene unas variables declaradas para poder usar colores directamente desde este archivo (podeis abrirlo y echarle un ojo) y así con el esto. Otro por ejemplo es el #include «fr_tiles.inc» // used for DrawBox, que contiene el código hexadecimal de los tiles etc. La cabecera de este fichero la podemos dejar tal y como está.
Lo que hace que nuestra rom arranque, es el método Main() el cual es el que hace que nuestra rom haga algo. Es importante indicar, que NUNCA NUNCA, este proceso puede terminar, explico…La rutina de carga del juego es lineal, si en el método Main(), no existe algo para hacer, el método terminará, y provocará un error, entonces, nuestro método Main() debe incluir algo que siempre haga que este funcionando, para ello, como en el ejemplo, añadimos la rutina While(1). Esto hará que mientras (while en ingles) el valor sea 1, este bucle estará funcionando continuamente y no cerrará la instrucción Main() a no ser que la cerremos nosotros con otros proceso pero eso ya es otra cosa.
Otro método que debe estar cargado si o si en el Main() es el InitNGPC(); Este método inicializa la actividad con la NGPC y es necesario que esté, si no no va a hacer nada.
Entonces, hagamos nuestro fichero, pongamos lo siguiente:
/* MaxiDemo Lots of little demos combined into one bigger one. */ #if 1 // header files #include "ngpc.h" // required #include "carthdr.h" // required #include "library.h" // NGPC routines #include <stdlib.h> // std C routines #include <stdio.h> #include "colors.h" // used for bitmapdemo2 // data files #include "colors.inc" // used for colordemo #include "sample.inc" // used for neodemo #include "sprites.inc" // used for sprdemo #include "fr_tiles.inc" // used for DrawBox #endif void main(void) { // Inicio de ejcución del juego. rstat = USR_BOOT; InitNGPC(); while (1) { } } // Fin de rutina Main
Guardamos nuestro fichero. Ahora mismo no hace nada, es simplemente un archivo con unas lineas sin funcionamiento visual. Vamos a añadir un hello World. Para ellos, vamos a usar el método PrintString()
Este método es muy simple, inserta en un plano (1 o 2) un texto, y luego lo muestra en pantalla, así de simple. ¿Cómo he encontrado este método? Fácil, si quereis investigar, y si os fijais, en el fichero maxidemo.c, en su cabecera hay un #include de un fichero llamado library.h. que a su vez, este fichero internamente hace un include del fichero library.c. Este fichero, pertenece al framework, y contiene TODOS los métodos que podemos utilizar para trabajar con la NGPC. Abramos este fichero library.c y busquemos el método PrintString(). Su código es el siguiente:
void PrintString(u8 Plane, u8 Palette, u8 XPos, u8 YPos, const char * theString) { ////////////////////////////////////////////////////////////////////////////// // PrintString // Displays a string on the screen at the specified location // Inputs: // Plane - Scroll Plane to clear SCR_1_PLANE or SCR_2_PLANE // PalleteNo - 0-15 the palette number to set // XPos - X Position (0 to 19) // YPos - Y Position (0 to 18) // theString - The string to be displayed ////////////////////////////////////////////////////////////////////////////// u16 * Screen;switch (Plane) { case SCR_1_PLANE: Screen = SCROLL_PLANE_1; break; case SCR_2_PLANE: Screen = SCROLL_PLANE_2; break; default: return; } while (*theString) { u16 Offset = ((u16)YPos * 32) + XPos; u16 Value = *theString + ((u16)Palette << 9); Screen[Offset] = Value; theString++; XPos++; } }
No voy a explicar todo su código, ya dije que no voy a enseñar a programar, pero fijémosnos en sus parámetros:
void PrintString(u8 Plane, u8 Palette, u8 XPos, u8 YPos, const char * theString)
Ahora desglosado:
void = esto significa que el método no devuelve nada.
PrintString = nombre del método.
u8 Plane = Variable de tipo u8 (es un entero por decirlo así que permite valores desde 0 a 255) Este parámetro, hace referencia a el Nº de Plano que vamos a usar.
u8 Palete = Como el anterior, pero este indica el nº de paleta que vamos a usar.
u8 Xpos = Posición en pantalla en eje X.
u8 YPos = Posición en pantalla en eje Y.
const cahr * theString = Variable de referencia (*) de tipo carácter, que será el texto que se va a mostrar.
Ahora explicado esto lo usaremos de la siguiente manera:
PrintString(SCR_1_PLANE, 1, 1, 1, "Hello World");
Es simple, indicamos en el parámetro 1, el plano. Para usar los planos tenemos dos variables declaradas en el framework, llamadas SCR_1_PLANE que hace referencia al plano principal Y luego está el SCR_2_PLANE, que hace referencia al plano de fondo. Luego, indicamos en nº de paleta, como no tenemos ninguna declarada y es la primera llamada que hacemos, ponemos la 1, aunque se podría poner cualqueir otro número. Luego posición X y Y (1,1) y al final, entre comillas, el texto ¿Es fácil no?
Ahora, para incluir esto en nuestro código, pues, dentro del método Main(), y dentro del While (recordeos para que sirvía) añadimos la línea como la he indicado
void main(void) { // Inicio de ejcución del juego. rstat = USR_BOOT; InitNGPC(); while (1) { PrintString(SCR_1_PLANE, 1, 1, 1, "Hello World"); } } // Fin de rutina Main
Ya tenemos nuestro programa hecho. La explicación de esto es:
A) Cargamso el método Main()
B) Inicializamos la Pocket con InitNGPC();
C) Creamos una sentencia While(1) {} para evitar que se salga el programa del método Main()
D) Añadimos la linea para mostrar el texto; PrintString(SCR_1_PLANE, 1, 1, 1, «Hello World»);
Listo guardamos el fichero y ya tenemos el programa hecho. Ahora solo queda compilarlo para obtener la ROM.
PASO 4
Para compilar debemos abrir una consola de comandos de Windows y debe ser XP, ya que el comando MAKE sólo está disponible en la consola de comandos de Windows XP y no en versiones superiores
Antesde nada, tenemos que tener un fichero que añade ciertas variables de entorno al sistema. Yo me volví loco para entender este apartado, así que copio y pego el texto y guardais el fichero en C:\ con nombre env.bat (o podéis descargarlo aquí).
path=%path%;C:ngpcbinsT900bin SET THOME=C:ngpcbinsT900
Abrimos la consola de comandos (Inicio/Ejecutar/cmd.exe) y accedemos al directorio C:\ a través de la consola de comandos, y ejecutamos el archivo env.bat, para ello, una vez colocados en C:\ escribimos env.bat y damos a Enter.
Ya tenemos las variables de entorno cargadas. Ahora el siguiente paso es acceder al directorio del framework (C:\frmwrk04\), donde tenemos nuestro fichero maxidemo.c
Una vez dentro, escribimos make y damos a enter.
A partir de ahora pueden pasar 2 cosas:
A) Que se compile correctamente, creando la ROM en el directorio del framework, llamada maxidemo.ngp
B) Que nos de un error. SI da error es porque algo mal has escrito en el fichero maxidemo.c. Normalmente te indicará la linea
Os pongo un ejemplo de una compilación correcta y una incorrecta.
Ejemplo Correcto. Aqui la ROM se ha compilado correctamente y ya podemos arrancarla en nuestro emulador favorito, o en tu cartucho flash Si nos fijamos, no hay ningun error.
Ejemplo Incorrecto. Aqui he provocado un error y el compilador (hace lo que puede) nos indica la linea donde está el error. En mi caso (en el tuyo puede ser otro), se debe a que cuando añadí la linea PrintString(SCR_1_PLANE, 1, 1, 1, «Hello World»); no le puse el punto y coma al final. Pero siempre el compilador mostrará en pantalla mensajes de Error para identifica rel fallo, acompañado de la línea de error. Aconsejo empezar a buscar desde la primera línea indicada por el compilador.
Y esto es lo básico para desarrollar, a partir de aquí ya depende de vosotros o de quien queira progresar en esto. Me podeis preguntar todas las dudas que tengais que os intentaré ayudar.
Saludos y espero ver vuestra capturas de vuestro emulador con la ROM cargada
Espero que os haya gustado.
Últimos comentarios