PDA

Ver la versión completa : [HILO OFICIAL] GameBoy Advance & GameBoy Development



Páginas : [1] 2 3 4

jduranmaster
13/06/2010, 16:50
http://desmond.imageshack.us/Himg813/scaled.php?server=813&filename=poratada.jpg&res=medium
Hola a todos. Despúés de algún tiempo he decidio abrir este hilo, pues el desarrollo de HomeBrew para GameBoy y GameBoy Advance me parece un tema lo suficientemente interesante como para tratarlo por aqui. La idea es que en este hilo expongamos nuestras roms y HomeBrew realizado para estos sistemas y compartamos conocimientos.

Como algunos sabeis el desarrollo de de HomeBrew para estos sistemas se basa en unos kits de dasorrollo que permiten al usuario realizar software en lenguaje de programación C.

En el caso de GameBoy el kit de desarrollo es el GBDK, y además es interesante bajarse herramientas adicionales para la edición de gráficos como las siguientes:

GBTD (http://www.devrs.com/gb/hmgd/gbtd.html)

GBMB (http://www.devrs.com/gb/hmgd/gbmb.html)

ambas permiten la edición y generación de mapas y gráficos para los juegos que se desarrollen y guardan los resultados en un formato entedible por el GBDK.

por otro lado tenemos otra herramienta muy interesante es el PCX2GB que permite convertir imagenes en formato PCX al formato que el GBDK entiende a la hora de programar en C. Tmb puede ser interesante para la gente que desee programar en ensamblador tener a mano el RGBDK (tanto RGBDK como GBDK son descargables desde las páginas de desarrollo) GBDK (http://www.loirak.com/gameboy/gbprog.php)

En el caso de GameBoy Advance el kit de desarrollo se llama devkitadv y actualmente se encuentra disponible en SourceForge la revisión 3 del Core 5.

En este caso tmb puede ser interesante acompañarse de utilidades complementarias para le manejo de gráficos. Todas estas herramientas complementarias se pueden encontrar aqui (http://www.gbadev.org).

Haciendo una recopilación de Enlaces tenemos:

GameBoy Advance:

SourceForge: devkitadv-r5-beta-3 (lo buscaís ahi)

Herramientas adicionales de tratamiento de Gráficos y demás (http://www.gbadev.org).

DevkitPro + Tutoriales (http://www.coranac.com/tonc/text/toc.htm)

Tutorial Básico sobre Ensamblador para el ARM de GBA (inglés) (http://www.l8night.co.uk/mwynn/gbadev/asmdocs/gba-arm-asm.html)

Vamos a ir usando los dos kits desarrollo para hacer los ejemplos, en cualquier caso cuando se realice un ejemplo y se suba se indicará con herramientas i kits esta hecho.

GameBoy:

GBDK (http://www.loirak.com/gameboy/gbprog.php)

GBTD (http://www.devrs.com/gb/hmgd/gbtd.html)

GBMB (http://www.devrs.com/gb/hmgd/gbmb.html)

Curso de la Universidad de Wichita (http://cratel.wichita.edu/cratel/ECE238Spr08)

Tutorial de xzakox sobre programación en ensamblador para GameBoy (http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador)

A continuación dejo algunas caracteristicas reseñables de ambos sistemas:


GameBoy Advance: (Wiki)


Sucesora de la popular Game Boy, es capaz de ejecutar casi todo el software escrito para la Game Boy y la Game Boy Color, así como nuevos programas desarrollados teniendo en cuenta las mayores capacidades del sistema. Al igual que prácticamente cualquier consola 2D, tiene soporte por hardware para dibujar la pantalla, aunque las capacidades de la GameBoy Advance resultaron sorprendentes en su presentación: hasta 128 sprites simultáneos y hasta cuatro planos de scroll, que pueden ser escalados, rotados y mezclados sin consumir tiempo de la CPU principal.

Cuenta con un procesador ARM propio de 32 bits a 16,7 MHz, basado en la arquitectura RISC, con una potencia suficiente para permitir el desarrollo de juegos utilizando el Lenguaje de programación C. El microprocesador ARM es capaz de ejecutar tanto un juego de instrucciones con un tamaño de instrucción de 32 bits, como un juego de instrucciones llamado "Thumb" de un tamaño de 16 bit (pero igualmente, de 32 bits). El sistema, además, lleva un procesador Z80 a 2 MHz para dar soporte al software de Game Boy clásica y color, pero sus dos procesadores no pueden estar funcionando a la vez debido a diferencias de voltaje y utilización del bus.

La pantalla LCD es capaz de mostrar una retícula de 240x160 píxeles en color de 15 bits (32768 colores). Esta pantalla incluye más píxeles que la original Game Boy (160x144). Cuando se ejecutan juegos anteriores, el usuario puedo pulsar el botón L ó el R para conmutar la pantalla entre mostrar 160x144 con un borde negro o bien escalar a 240x144. Los primeros juegos exhiben paletas de color muy oscuras porque la pantalla en el kit de desarrollo era mucho más luminosa que la de las unidades comercializadas. Los títulos más recientes usan una corrección gamma en sus paletas.

El generador de imágenes de la GBA tiene seis modos de visualización (tres basados en bloques y tres basados en mapas de bit) y 96 KB de RAM dedicada. En los modos de visualización basados en bloques, el sistema puede gestionar cuatro capas pixel-a-pixel, dos capas pixel-a-pixel y una capa afín, o bien dos capas afines, y usa 64 KB de RAM para los datos de celdas y mapas y 32 KB para los datos de los 'sprites'. En los modos de mapa de bit, puede mostrar un mapa de bit grande de 16 bits, dos mapas de bits de 8 bit (en modo paginado) o bien un mapa de bit de 16 bit pequeño (con paginación), usando 80 KB de RAM para los datos de mapa y 16 KB para los datos de 'sprite'. En todos los modos, puede mostrar hastra 128 'sprites' (pequeños objetos móviles individuales) de 8x8 hasta 64x64 pixels en color indexado de 4 u 8 bits. Cada 'sprite' puede ser dibujado mediante mapeado directo a píxel o bien por mapeado afín.

La interfaz de la GBA con el cartucho ROM incluye únicamente un bus de dirección de 24 bits multiplexado con un bus de datos de 16 bits. (La consola Intellivision de Mattel ya había usado anteriormente un bus multiplexado). Esta configuración limita la memoria direccionable directamente a 16 megapalabras binarias (es decir, 256 megabits o 32 megabytes). Sin embargo, si el cartucho dispone de hardware de conmutación de bancos puede expandir esta cantidad mediante el control por software de las líneas superiores de direccionamiento, conmutando otras partes de la ROM en el espacio de direccionamiento de la GBA.

La GBA también tiene un puerto serie para conectarse con otras unidades GBA en una configuración similar a la red token ring sobre una topología física de bus. La GBA también puede recibir 256 KB en código de arranque a través del puerto, incluso cuando no tiene un cartucho conectado (lo que se conoce como multiboot o netboot). Esto se utiliza en las conexiones multijugador, donde varias GBA pueden funcionar con un único cartucho: la GBA que tiene el cartucho envía el código inicial a las que no lo tienen. El puerto serie puede (con el cable adecuado) conectarse a un puerto serie RS-232 para ayudar en la depuración e, hipotéticamente, jugar a través de Internet, si bien aún no se ha implementado una pila TCP/IP en la GBA.

http://www.kasparian.fr/wp-content/uploads/2009/05/gba.png

Video

240x160 pixel, 15bit color LCD screen. The original GBA screen was not backlit, but the SP's and Micro's are.
3 bitmap modes and 3 tilemap modes and sprites.
4 individual tilemap layers (backgrounds) and 128 sprites (objects).
Affine transformations (rotate/scale/shear) on 2 backgrounds and 32 objects.
Special graphic effects: mosaic, additive blend, fade to white/black.

Sound

6 channels total
4 tone generators from the original GameBoy: 2 square wave, 1 general wave and one noise generator.
2 'DirectSound' channels for playing samples and music.

Miscellaneous
10 buttons (or keys): 4-way directional pad, Select/Start, fire buttons A/B, shoulder buttons L/R.
14 hardware interrupts.
4-player multiplayer mode via a multiboot cable.
Optional infrared, solar and gyroscopic interfaces. Other interfaces have also been made by some.
Main programming platforms: C/C++ and assembly, though there are tools for Pascal, Forth, LUA and others as well. Easy to start with, yet hard to truly master.

As said, the GBA runs on a ARM7tdmi RISC chip at 16.78 MHz (224 cycles/second). It is a 32bit chip that can run on two different instruction sets. First, there's is ARM code, which is a set of 32bit instructions. Then there's THUMB, which uses 16bit instructions. THUMB instructions are a subset of the ARM instruction set; since the instructions are shorter, the code can be smaller, but their power is also reduced. It is recommended that normal code be THUMB code in ROM, and for time-critical code to be ARM code and put in IWRAM. Since all tonc-demos are still rather simple, most (but not all) code is THUMB code.

GameBoy: (Wiki)

http://wildgames.es/wp-content/uploads/2008/09/game_boy_color.jpg

CPU: versión modificada del Z80 de 8 bits trabajando a 4.194304 MHz
RAM: 8kB internos de SRAM
VRAM: 8kB internos
Sonido: 4 canales. La GB sólo tiene un altavoz, pero tiene salida para auriculares con los cuales se puede escuchar en stereo.
Pantalla: LCD reflectiva con una resolución de 160x144 pixeles
Colores: 4 tonos de gris
Sprites simultáneos en pantalla: 40 sprites cada uno de 8x8 u 8x16 [seleccionable]
Comunicaciones: puerto serie
Alimentación: 4 pilas AA
Usuarios: hasta 2 vía cable link conectado al puerto de serie y un Game Boy con un cartucho de juego por cada usuario; o 4 con el "Four Player Adapter"

Pues nada al lio. Aqui os presento un pequeño ejemplo realizado para GBA a modo de "Hola Mundo" que he realizado en un ratito. Ya se que hay cosas del código que se pueden dejar más vistosas y en muchos casos debería haber empleado bucles "FOR" pero como es el primer ejemplo y se trata de aprender tampoco me preocuba mucho.


/*
@author: jduranmaster
*/

/*En el ejemplo trabajamos con el modo grafico 3 de GBA. este modo grafico tiene un tamqaño de 240x160,
donde cada pixel tiene 16 bits.*/

//definimos la macro.
#define RGB16(r,g,b) ((r)+(g<<5)+(b<<10))

/*vemos que el comportamiento de la macro definida es coger el color azul y desplazarlo 10 bits, coger el color verde y
desplazarlo 5 bits, para finalmente añadir el valor del color rojo. Los valores a utilizar estan dentro del rango 0..31 ya que
2^5 = 32.
*/


int main()
{
char x,y;
unsigned short* Screen = (unsigned short*)0x6000000;
*(unsigned long*)0x4000000 = 0x403; // modo gráfico 3, bg2 on

// con esto rellenamos la pantalla de color azul.
for(x = 0; x<240;x++){
for(y = 0; y<160; y++){
Screen[x+y*240] = RGB16(0,0,15);
}//fin del for de Y.
}//fin del for de X.

//pintamos una J.
x=35;y=39;Screen[x+y*240] = RGB16(31,31,31); x=35;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=37;Screen[x+y*240] = RGB16(31,31,31); x=35;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=35;Screen[x+y*240] = RGB16(31,31,31); x=35;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=33;Screen[x+y*240] = RGB16(31,31,31); x=35;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=31;Screen[x+y*240] = RGB16(31,31,31); x=35;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=29;Screen[x+y*240] = RGB16(31,31,31); x=35;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=35;y=27;Screen[x+y*240] = RGB16(31,31,31); x=35;y=26;Screen[x+y*240] = RGB16(31,31,31);

for (x = 20; x < 35; x++)
Screen[x+40*240] = RGB16(31,31,31);

//pintamos una D

x=40;y=39;Screen[x+y*240] = RGB16(31,31,31); x=40;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=37;Screen[x+y*240] = RGB16(31,31,31); x=40;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=35;Screen[x+y*240] = RGB16(31,31,31); x=40;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=33;Screen[x+y*240] = RGB16(31,31,31); x=40;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=31;Screen[x+y*240] = RGB16(31,31,31); x=40;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=29;Screen[x+y*240] = RGB16(31,31,31); x=40;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=40;y=27;Screen[x+y*240] = RGB16(31,31,31); x=40;y=26;Screen[x+y*240] = RGB16(31,31,31);

for (x = 40; x < 48; x++)
Screen[x+40*240] = RGB16(31,31,31);

x=48;y=37;Screen[x+y*240] = RGB16(31,31,31); x=48;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=48;y=35;Screen[x+y*240] = RGB16(31,31,31); x=48;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=48;y=33;Screen[x+y*240] = RGB16(31,31,31); x=48;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=48;y=31;Screen[x+y*240] = RGB16(31,31,31); x=48;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=48;y=29;Screen[x+y*240] = RGB16(31,31,31); x=48;y=28;Screen[x+y*240] = RGB16(31,31,31);

for (x = 40; x < 48; x++)
Screen[x+25*240] = RGB16(31,31,31);

//pintamos una U

x=53;y=39;Screen[x+y*240] = RGB16(31,31,31); x=53;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=37;Screen[x+y*240] = RGB16(31,31,31); x=53;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=35;Screen[x+y*240] = RGB16(31,31,31); x=53;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=33;Screen[x+y*240] = RGB16(31,31,31); x=53;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=31;Screen[x+y*240] = RGB16(31,31,31); x=53;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=29;Screen[x+y*240] = RGB16(31,31,31); x=53;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=53;y=27;Screen[x+y*240] = RGB16(31,31,31); x=53;y=26;Screen[x+y*240] = RGB16(31,31,31);

for (x = 53; x < 61; x++)
Screen[x+40*240] = RGB16(31,31,31);

x=61;y=39;Screen[x+y*240] = RGB16(31,31,31); x=61;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=37;Screen[x+y*240] = RGB16(31,31,31); x=61;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=35;Screen[x+y*240] = RGB16(31,31,31); x=61;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=33;Screen[x+y*240] = RGB16(31,31,31); x=61;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=31;Screen[x+y*240] = RGB16(31,31,31); x=61;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=29;Screen[x+y*240] = RGB16(31,31,31); x=61;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=61;y=27;Screen[x+y*240] = RGB16(31,31,31); x=61;y=26;Screen[x+y*240] = RGB16(31,31,31);

//pintamos una R

x=66;y=39;Screen[x+y*240] = RGB16(31,31,31); x=66;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=37;Screen[x+y*240] = RGB16(31,31,31); x=66;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=35;Screen[x+y*240] = RGB16(31,31,31); x=66;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=33;Screen[x+y*240] = RGB16(31,31,31); x=66;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=31;Screen[x+y*240] = RGB16(31,31,31); x=66;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=29;Screen[x+y*240] = RGB16(31,31,31); x=66;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=27;Screen[x+y*240] = RGB16(31,31,31); x=66;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=66;y=40;Screen[x+y*240] = RGB16(31,31,31);

for (x = 66; x < 74; x++)
Screen[x+25*240] = RGB16(31,31,31);

for (x = 66; x < 74; x++)
Screen[x+32*240] = RGB16(31,31,31);

x=74;y=32;Screen[x+y*240] = RGB16(31,31,31); x=74;y=31;Screen[x+y*240] = RGB16(31,31,31);
x=74;y=30;Screen[x+y*240] = RGB16(31,31,31); x=74;y=29;Screen[x+y*240] = RGB16(31,31,31);
x=74;y=28;Screen[x+y*240] = RGB16(31,31,31); x=74;y=27;Screen[x+y*240] = RGB16(31,31,31);
x=74;y=26;Screen[x+y*240] = RGB16(31,31,31); x=74;y=25;Screen[x+y*240] = RGB16(31,31,31);

x=66;y=32;Screen[x+y*240] = RGB16(31,31,31); x=67;y=33;Screen[x+y*240] = RGB16(31,31,31);
x=68;y=34;Screen[x+y*240] = RGB16(31,31,31); x=69;y=35;Screen[x+y*240] = RGB16(31,31,31);
x=70;y=36;Screen[x+y*240] = RGB16(31,31,31); x=71;y=37;Screen[x+y*240] = RGB16(31,31,31);
x=72;y=38;Screen[x+y*240] = RGB16(31,31,31); x=73;y=39;Screen[x+y*240] = RGB16(31,31,31);
x=74;y=40;Screen[x+y*240] = RGB16(31,31,31);

//pintamos una A

x=79;y=39;Screen[x+y*240] = RGB16(31,31,31); x=79;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=37;Screen[x+y*240] = RGB16(31,31,31); x=79;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=35;Screen[x+y*240] = RGB16(31,31,31); x=79;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=33;Screen[x+y*240] = RGB16(31,31,31); x=79;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=31;Screen[x+y*240] = RGB16(31,31,31); x=79;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=29;Screen[x+y*240] = RGB16(31,31,31); x=79;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=27;Screen[x+y*240] = RGB16(31,31,31); x=79;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=79;y=40;Screen[x+y*240] = RGB16(31,31,31);

for (x = 79; x < 87; x++)
Screen[x+25*240] = RGB16(31,31,31);

for (x = 79; x < 87; x++)
Screen[x+32*240] = RGB16(31,31,31);

x=87;y=39;Screen[x+y*240] = RGB16(31,31,31); x=87;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=37;Screen[x+y*240] = RGB16(31,31,31); x=87;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=35;Screen[x+y*240] = RGB16(31,31,31); x=87;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=33;Screen[x+y*240] = RGB16(31,31,31); x=87;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=31;Screen[x+y*240] = RGB16(31,31,31); x=87;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=29;Screen[x+y*240] = RGB16(31,31,31); x=87;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=27;Screen[x+y*240] = RGB16(31,31,31); x=87;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=87;y=40;Screen[x+y*240] = RGB16(31,31,31);

//pintamos una N

x=93;y=39;Screen[x+y*240] = RGB16(31,31,31); x=93;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=37;Screen[x+y*240] = RGB16(31,31,31); x=93;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=35;Screen[x+y*240] = RGB16(31,31,31); x=93;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=33;Screen[x+y*240] = RGB16(31,31,31); x=93;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=31;Screen[x+y*240] = RGB16(31,31,31); x=93;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=29;Screen[x+y*240] = RGB16(31,31,31); x=93;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=27;Screen[x+y*240] = RGB16(31,31,31); x=93;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=93;y=40;Screen[x+y*240] = RGB16(31,31,31);

x=93;y=25;Screen[x+y*240] = RGB16(31,31,31); x=94;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=95;y=27;Screen[x+y*240] = RGB16(31,31,31); x=96;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=97;y=29;Screen[x+y*240] = RGB16(31,31,31); x=98;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=99;y=31;Screen[x+y*240] = RGB16(31,31,31); x=100;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=101;y=33;Screen[x+y*240] = RGB16(31,31,31); x=102;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=103;y=35;Screen[x+y*240] = RGB16(31,31,31); x=104;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=105;y=37;Screen[x+y*240] = RGB16(31,31,31); x=106;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=107;y=39;Screen[x+y*240] = RGB16(31,31,31); x=108;y=40;Screen[x+y*240] = RGB16(31,31,31);

x=108;y=39;Screen[x+y*240] = RGB16(31,31,31); x=108;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=37;Screen[x+y*240] = RGB16(31,31,31); x=108;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=35;Screen[x+y*240] = RGB16(31,31,31); x=108;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=33;Screen[x+y*240] = RGB16(31,31,31); x=108;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=31;Screen[x+y*240] = RGB16(31,31,31); x=108;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=29;Screen[x+y*240] = RGB16(31,31,31); x=108;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=27;Screen[x+y*240] = RGB16(31,31,31); x=108;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=108;y=40;Screen[x+y*240] = RGB16(31,31,31); x=108;y=25;Screen[x+y*240] = RGB16(31,31,31);

//pintamos "-"

for (x = 113; x < 121; x++)
Screen[x+32*240] = RGB16(31,31,31);

// pintamos "2010"

for (x = 126; x < 134; x++)
Screen[x+32*240] = RGB16(31,31,31);

x=126;y=39;Screen[x+y*240] = RGB16(31,31,31); x=126;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=126;y=37;Screen[x+y*240] = RGB16(31,31,31); x=126;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=126;y=35;Screen[x+y*240] = RGB16(31,31,31); x=126;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=126;y=33;Screen[x+y*240] = RGB16(31,31,31); x=126;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=134;y=31;Screen[x+y*240] = RGB16(31,31,31); x=134;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=134;y=29;Screen[x+y*240] = RGB16(31,31,31); x=134;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=134;y=27;Screen[x+y*240] = RGB16(31,31,31); x=134;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=134;y=40;Screen[x+y*240] = RGB16(31,31,31); x=134;y=25;Screen[x+y*240] = RGB16(31,31,31);

for (x = 126; x < 134; x++)
Screen[x+40*240] = RGB16(31,31,31);

for (x = 126; x < 134; x++)
Screen[x+25*240] = RGB16(31,31,31);

x=139;y=39;Screen[x+y*240] = RGB16(31,31,31); x=139;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=37;Screen[x+y*240] = RGB16(31,31,31); x=139;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=35;Screen[x+y*240] = RGB16(31,31,31); x=139;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=33;Screen[x+y*240] = RGB16(31,31,31); x=139;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=31;Screen[x+y*240] = RGB16(31,31,31); x=139;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=29;Screen[x+y*240] = RGB16(31,31,31); x=139;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=27;Screen[x+y*240] = RGB16(31,31,31); x=139;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=139;y=40;Screen[x+y*240] = RGB16(31,31,31); x=139;y=25;Screen[x+y*240] = RGB16(31,31,31);

for (x = 139; x < 147; x++)
Screen[x+25*240] = RGB16(31,31,31);

for (x = 139; x < 147; x++)
Screen[x+40*240] = RGB16(31,31,31);

x=147;y=39;Screen[x+y*240] = RGB16(31,31,31); x=147;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=37;Screen[x+y*240] = RGB16(31,31,31); x=147;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=35;Screen[x+y*240] = RGB16(31,31,31); x=147;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=33;Screen[x+y*240] = RGB16(31,31,31); x=147;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=31;Screen[x+y*240] = RGB16(31,31,31); x=147;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=29;Screen[x+y*240] = RGB16(31,31,31); x=147;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=27;Screen[x+y*240] = RGB16(31,31,31); x=147;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=147;y=40;Screen[x+y*240] = RGB16(31,31,31); x=147;y=25;Screen[x+y*240] = RGB16(31,31,31);

x=152;y=39;Screen[x+y*240] = RGB16(31,31,31); x=152;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=37;Screen[x+y*240] = RGB16(31,31,31); x=152;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=35;Screen[x+y*240] = RGB16(31,31,31); x=152;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=33;Screen[x+y*240] = RGB16(31,31,31); x=152;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=31;Screen[x+y*240] = RGB16(31,31,31); x=152;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=29;Screen[x+y*240] = RGB16(31,31,31); x=152;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=27;Screen[x+y*240] = RGB16(31,31,31); x=152;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=152;y=40;Screen[x+y*240] = RGB16(31,31,31); x=152;y=25;Screen[x+y*240] = RGB16(31,31,31);

x=157;y=39;Screen[x+y*240] = RGB16(31,31,31); x=157;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=37;Screen[x+y*240] = RGB16(31,31,31); x=157;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=35;Screen[x+y*240] = RGB16(31,31,31); x=157;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=33;Screen[x+y*240] = RGB16(31,31,31); x=157;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=31;Screen[x+y*240] = RGB16(31,31,31); x=157;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=29;Screen[x+y*240] = RGB16(31,31,31); x=157;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=27;Screen[x+y*240] = RGB16(31,31,31); x=157;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=157;y=40;Screen[x+y*240] = RGB16(31,31,31); x=157;y=25;Screen[x+y*240] = RGB16(31,31,31);

for (x = 157; x < 165; x++)
Screen[x+25*240] = RGB16(31,31,31);

for (x = 157; x < 165; x++)
Screen[x+40*240] = RGB16(31,31,31);

x=165;y=39;Screen[x+y*240] = RGB16(31,31,31); x=165;y=38;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=37;Screen[x+y*240] = RGB16(31,31,31); x=165;y=36;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=35;Screen[x+y*240] = RGB16(31,31,31); x=165;y=34;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=33;Screen[x+y*240] = RGB16(31,31,31); x=165;y=32;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=31;Screen[x+y*240] = RGB16(31,31,31); x=165;y=30;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=29;Screen[x+y*240] = RGB16(31,31,31); x=165;y=28;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=27;Screen[x+y*240] = RGB16(31,31,31); x=165;y=26;Screen[x+y*240] = RGB16(31,31,31);
x=165;y=40;Screen[x+y*240] = RGB16(31,31,31); x=165;y=25;Screen[x+y*240] = RGB16(31,31,31);

for (x = 25; x < 165; x++)
Screen[x+50*240] = RGB16(31,31,31);

for (x = 25; x < 165; x++)
Screen[x+20*240] = RGB16(31,31,31);


while(1){}//bucle infinito

}//fin de programa

el resultado por pantalla es algo similar a esto:



Bueno pues esto es todo. Ire actualizando según vaya desarrollando cosas nuevas.

PD: os dejo la ROM para que la proveis es vuestros emuladores. (no se si tirara en el de Wiz, porque solo he probado en el VisualBoy Advance).

jduranmaster
13/06/2010, 16:54
aqui esta la captura de pantalla con el resultado.

xzakox
13/06/2010, 17:20
Encantado, por aqui uno con algo de experiencia en el desarrollo para la gameboy.
Y si, realmente el GBDK está muy bien para aprender, pero tiene limitaciones bastante grandes, muchas dadas simplemente por la potencia de la plataforma y sus peculiariaridades. Si uno se quiere poner a hacer algo realmente serio con la GameBoy, realmente es interesante ponerse a mirar el ensamblador.
No es tan dificil como parece, el ensamblador del z80 es bastante bonito y sencillo, y el hardware de la gameboy tiene bastantes funcionalidades para el manejo de gráficos y demás, que hacen el desarrollo en ASM más sencillo.
Con un buen ensamblador con soporte potente de macros, como el rgbasm, y algunas librerias que se prepare uno, el desarrollo en asm para la gb puede ser bastante entretenido.
Os dejo un par de enlaces a cursos de asm de gameboy.
El primero, un curso de la universidad de Wichita sobre desarrollo en asm, en que usaron la gameboy como plataforma, muy bueno, con recursos, ejemplos, librerias, etc:
http://cratel.wichita.edu/cratel/ECE238Spr08

Y otro menos avanzado e incompleto, pero muy bien explicado paso a paso, asmschool:
http://gameboy.mongenel.com/asmschool.html

Os dejo además el wiki de gbdev, donde estamos metiendo toda la documentacion que podemos sobre la gameboy, si alguien quiere colaborar, que avise :-)
http://gbdev.gg8.se/wiki/articles/Main_Page

GameMaster
13/06/2010, 17:21
Muy bueno aporte, yo hace años hice algunas cositas.

http://remondes.net/GecaSoft/Game Boy Advance Demos.rar

jduranmaster
13/06/2010, 19:38
un placer tenerte por aqui xzakox. Y muchas gracias por poner los enlaces a la documentación del ensamblador para poder usarlo en los desarrollos. Ya sabes, si haces alguna cosilla para Gameboy no dudes en ponerla por aqui.

< - >

Muy bueno aporte, yo hace años hice algunas cositas.

http://remondes.net/GecaSoft/Game Boy Advance Demos.rar

gracias por subirlas. La idea es que los trabajos nuevos que vayamos haciendo se puedan subir por aqui para compartirlos con todos.

< - >
a ver si alquien que tenga GBA con CartFlash puede probar la Rom que he coldago para probar si funciona en una GBA real.

_-Caleb-_
13/06/2010, 19:53
yo cuando encuenrte la maleta del netbook y el adaptador minisd lo pruebo :)

tanuquillo
13/06/2010, 19:59
oh que bueno. como me gusta a mi esto lastima que no tenga ni idea de programar.
yo aunque no es programar he usado mi gb micro con fotos que me hacia yo y con el moon shell me ponia datos de los aeropuertos para el simulador de vuelo.
con las emisoras de radio las pistas y sus datos de entrada y todo eso. pero claro eso no es programar es poner fotos y punto.
yo siempre he querido usar la gba como un monitor usando el cable de link por usb o algo pero eso no creo que sea posible

jduranmaster
13/06/2010, 20:03
yo cuando encuenrte la maleta del netbook y el adaptador minisd lo pruebo :)

cuando puedas. de todas formas la intención de l hilo es que la gente se anime a programar usando los kits de desarrollo que hemos dejado en los enlaces de los posts iniciales. cualquier obra es bien recibida.


oh que bueno. como me gusta a mi esto lastima que no tenga ni idea de programar.
yo aunque no es programar he usado mi gb micro con fotos que me hacia yo y con el moon shell me ponia datos de los aeropuertos para el simulador de vuelo.
con las emisoras de radio las pistas y sus datos de entrada y todo eso. pero claro eso no es programar es poner fotos y punto.
yo siempre he querido usar la gba como un monitor usando el cable de link por usb o algo pero eso no creo que sea posible

bueno nunca es tarde para ponerse a programar algo. empezar con el GBDK para GameBoy es bastante sencillito. El kit de desarrollo de GBA puede ser algo más duro.

tSuKiYoMi
13/06/2010, 20:33
vaya gracias por crear este hilo. es muy interesante, y asi podemos de dejar de ensuciar el otro hilo de PAche sobre GAmeBoy. Bueno aunque sea una rom bastante mala de GB voy a subir la ROM de los mapaches. Espero contribuir con cosas mejores de ahora en adelante a este hilo.

gracias por poner los enlaces al kit de desarrollo de GBA jduran. y gracias a xzabox por poner la info de ensamblador para GB.

jduranmaster
13/06/2010, 21:06
cualquier aporte es bien recibido. En los proximos dias pondre tutos y codigo para incluir imagens de fondo en las roms, reproducción de sonidos (aun estoy empapandome de esto:D) y algunos otros efectos.

manirea
13/06/2010, 21:13
Yo sé donde pillar sdk oficiales de consolas, pondría link....pero no lo permite las normas.
(master system, snes, game boy.... XD)

Si quereis el sdk os lo digo por privado

tanuquillo
13/06/2010, 21:19
uff no se por que ahora me molan tanto las gameboys las tenia ahi muertas de risa hace tiempo pero es que es la magia de lo retro. pones cualquier jueguecillo chorra pero te tiras la tarde entera jugando y te acuerdas de que no necesitas next gen

jduranmaster
13/06/2010, 21:20
a mi por supuesto que me interesa. asi si que ya sabes.:awesome:

tSuKiYoMi
13/06/2010, 21:43
uff no se por que ahora me molan tanto las gameboys las tenia ahi muertas de risa hace tiempo pero es que es la magia de lo retro. pones cualquier jueguecillo chorra pero te tiras la tarde entera jugando y te acuerdas de que no necesitas next gen

no se la gameboy es una maquina que a mi personalmente me ha molado siempre a sigo jugando a sus juegos (en la Wiz claro).

xzakox
13/06/2010, 21:45
Yo sé donde pillar sdk oficiales de consolas, pondría link....pero no lo permite las normas.
(master system, snes, game boy.... XD)

Si quereis el sdk os lo digo por privado

Por favor :-)

jduranmaster
13/06/2010, 21:55
bueno chicos estoy haciendo pruebas para cargar imagenes en una ROM de GBA, y de momento parece que el PCX2GBA tiene mejores prestaciones que el de Gameboy (PCX2GB), lo cual en principio es normal, puesto que la GBA soporta mas colores colores y modos graficos.....XDDD (que obviedad), el caso que el PCX2GBA ofrece varios modos de exportar datos gráficos , uno de ellos consiste en tomar la imagen PCX generar a partir de ella un fichero .h con los datos en un tipo definido como USHORT, aqui os pongo el resultado:


#ifndef __sample__
#define __sample__
#define sample_WIDTH 240
#define sample_HEIGHT 160

const USHORT sampledata[] = {
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0 x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0842,0x 0421,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0421,0x0000,0x0000,0 x0421,0x0000,0x0842,0x1084,0x1084,0x0842,0x0842,0x 0842,0x0421,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0421,0x0421,0 x0000,0x0421,0x0421,0x0000,0x0000,0x0000,0x0000,0x 0000,0x0000,0x14a5,
0x6b5a,0x7fff,0x7bde,0x56b5,0x6f7b,0x7fff,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x7fff,0x7fff,0x7fff,0x294a,0x2d6b,0x7bde,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x56b5,0x 2d6b,0x18c6,0x5294,
0x7fff,0x7bde,0x5ef7,0x7fff,0x77bd,0x7fff,0x7fff,0 x7bde,0x56b5,0x739c,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x7fff,0x7bde,0x18c6,0x6318,0x7bde,0x7fff,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x14a5,0x7fff,0x 7fff,0x7fff,0x7fff,
0x6f7b,0x7bde,0x7bde,0x7fff,0x6b5a,0x0000,0x0000,0 x0000,0x0421,0x6739,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x5294,0x7fff,
0x77bd,0x7fff,0x7fff,0x5294,0x0000,0x0000,0x0000,0 x0000,0x0842,0x7bde,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x77bd,0x7fff,0x7fff,0x7fff,0x0842,0x6f7b,0x39ce,0 x0000,0x0000,0x5ad6,0x739c,0x739c,0x739c,0x14a5,0x 0421,0x6739,0x6318,
0x7bde,0x7bde,0x77bd,0x77bd,0x18c6,0x6f7b,0x0842,0 x3def,0x6b5a,0x5294,0x35ad,0x1ce7,0x739c,0x77bd,0x 4a52,0x4e73,0x7bde,
0x6f7b,0x7fff,0x7fff,0x7fff,0x56b5,0x39ce,0x3def,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x 7bde,0x318c,0x7bde,
0x2108,0x77bd,0x7fff,0x7fff,0x7fff,0x7fff,0x77bd,0 x77bd,0x4631,0x5ad6,0x7fff,0x7fff,0x7fff,0x739c,0x 5ef7,0x77bd,0x7fff,
0x7fff,0x7fff,0x7fff,0x6739,0x4210,0x1ce7,0x77bd,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7bde,0 x7bde,0x1ce7,0x2d6b,0x7bde,0x7bde,0x7bde,0x7bde,0x 7fff,0x56b5,0x7bde,
0x7bde,0x7fff,0x7fff,0x739c,0x7bde,0x7bde,0x77bd,0 x6f7b,0x4631,0x2d6b,0x0c63,0x0000,0x0421,0x0000,0x 0000,0x0421,0x18c6,
0x1ce7,0x5ad6,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x 35ad,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5ad6,0 x7fff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x 0000,0x0000,0x0000,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0 x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x 0000,0x0000,0x0000,
0x0000,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0 x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x7fff,0x4631,0x 0000,0x0000,0x0000,
0x0421,0x7fff,0x4e73,0x0000,0x0000,0x0000,0x0000,0 x0000,0x0000,0x0000,0x7bde,0x7fff,0x6f7b,0x0421,0x 0000,0x0000,0x0000,
0x0000,0x1ce7,0x739c,0x7fff,0x7fff,0x0000,0x0000,0 x0000,0x0000,0x35ad,0x7fff,0x7fff,0x7fff,0x7fff,0x 7fff,0x7fff,0x7fff,
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0 x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};

#endif


el siguiente paso es generar un main.c que carge esto en memoria y represente la imgen en la pantalla de la GBA. Por cierto alguien consiguio cargar mi anterior rom en una flashcart para GBA (lo pregunto porque ya se que funciona en VirtualBoy Advance)

[<_-_Ukyo_-_>]
13/06/2010, 22:16
hacia mucho que no entraba en los foros y me ha encatando este hilo. espero que hagais cosillas interesantes.:p

tSuKiYoMi
13/06/2010, 22:20
el siguiente paso es generar un main.c que carge esto en memoria y represente la imgen en la pantalla de la GBA. Por cierto alguien consiguio cargar mi anterior rom en una flashcart para GBA (lo pregunto porque ya se que funciona en VirtualBoy Advance)

entonces la herramienta esta PCX2GBA hace toda la conversión, no? funcionara en tdo caso de forma similar a como lo hacia el PCX2GB. por cierto alguien sabe como conseguir con el paint o con cualquier otro programa imagenes PCX de 8-bit. lo pregunto porque estuve probando el otro dia con el PCX2GB y me pedia como requisito que la imagen fuese PCX 8-bit y creo que la mia era de 24 bit.

xzakox
13/06/2010, 22:43
Los modos bitmap de la GBA están muy bien para hacer intros, pantallas de presentación, algún efecto... pero son demasiado pesados para los juegos, en la GBA la mayoria de los juegos se creaban usando alguno de los modos de tiles... es normal, los modos de tiles son estupendos para los juegos de este tipo, el hardware se encarga de controlar todo lo referente a dibujarlos, mezclarlos con el fondo, etc y tu solo tienes que pensar en moverlos y actualizarlos... es genial. Por eso si estais pensando en hacer jueguillos, en serio, miraros los modos de tiles, porque lo agradecereis enseguida.
:brindis:

jduranmaster
13/06/2010, 23:30
miraros los modos de tiles, porque lo agradecereis enseguida.:brindis:

apuntado. el tema es exponer toda la experiencia posible mediante ejemplos.

< - >

entonces la herramienta esta PCX2GBA hace toda la conversión, no? funcionara en tdo caso de forma similar a como lo hacia el PCX2GB. por cierto alguien sabe como conseguir con el paint o con cualquier otro programa imagenes PCX de 8-bit. lo pregunto porque estuve probando el otro dia con el PCX2GB y me pedia como requisito que la imagen fuese PCX 8-bit y creo que la mia era de 24 bit.

creo que con el paint te vale con salvar en BMP de 256 colores o de 16 colores segun te convenga y luego con cueñauiqer programa de conversión a PCX ya lo tendrias hecho.

saludos.

saucjedi
14/06/2010, 09:06
Devkitadv estaba bastante abandonado la última vez que lo miré y recomiendan en todas partes tirar de DevkitPro + libgba.

Si te animas a probar el DevkitPro (a mi ver bastante mejor) échale un ojo a este tutorial/libro que a mi me abrió los ojos: http://www.coranac.com/tonc/text/toc.htm

PS: También tengo SDKs oficiales de GBA. Lo mejor es tener a mano la documentación técnica que es la que tiene la última palabra. Podríamos poner versiones de los SDK y el que tenga la más alta que... ejem... lo comunique a los demás.

jduranmaster
14/06/2010, 09:08
Devkitadv estaba bastante abandonado la última vez que lo miré y recomiendan en todas partes tirar de DevkitPro + libgba.

Si te animas a probar el DevkitPro (a mi ver bastante mejor) échale un ojo a este tutorial/libro que a mi me abrió los ojos: http://www.coranac.com/tonc/text/toc.htm

PS: También tengo SDKs oficiales de GBA. Lo mejor es tener a mano la documentación técnica que es la que tiene la última palabra. Podríamos poner versiones de los SDK y el que tenga la más alta que... ejem... lo comunique a los demás.

me parece bien es una buena idea lo de las versiones de los SDK´s. Si puedes pasame los enlaces por MP saucjedi.

tSuKiYoMi
14/06/2010, 10:28
acabo de bajarme el DevKit Pro, por favor soucejedi pasanos los enlaces por MP a los otros kits de GBA que tengas.

jduranmaster
14/06/2010, 11:18
Aqui os traigo la primera ROM que permite cargar en pantalla de la GBA una imagen (tan simple como eso xDD). el caso es que como comentaba en el post de ayer, los pasos para poder cargar imagenes de fondo en la pantalla de la GBA son los siguientes:

1 - Generar la imagen de interés en formato PCX (valen imagenes de 8-bit y 24-bit), además, hay que tener en mente que como mucho la GBA soporta imagenes de 240x160, asi que no se os ocurra usar imagenes de mayor tamaño (mas que nada porque sino el PCX2GBA se queja).

2 - Usar el PCX2GBA y transformar la imagen PCX en un fichero .h de C que contiene un array de USHORT con los datos de la imagen en cuestión.

3- El ejemplo que os subo esta realizado con el devkitadv, luego para usar las imagenes convertidas en .h y que nos reconozca el tipo "USHORT" es preciso incluir en la carpeta de trabajo el fichero base.h que contiene tipos básicos del kit de desarrollo.


#ifndef BASE_HEADER
#define BASE_HEADER

#define BG0_ENABLE 0x100
#define BG1_ENABLE 0x200
#define BG2_ENABLE 0x400
#define BG3_ENABLE 0x800
#define OBJ_ENABLE 0x1000
#define WIN0_ENABLE 0x2000
#define WIN1_ENABLE 0x4000
#define WINOBJ_ENABLE 0x8000

#define BACK_BUFFER 0x10

//Registers
#define REG_DISPCNT *(ULONG*)0x4000000

//Screen Video Modes
#define MODE0 0x0
#define MODE1 0x1
#define MODE2 0x2
#define MODE3 0x3
#define MODE4 0x4
#define MODE5 0x5
#define SCREENWIDTH 240
#define SCREENHEIGHT 160

//Type Definitions
typedef unsigned char UCHAR; //8
typedef unsigned short USHORT; //16
typedef unsigned long ULONG; //32

typedef signed char CHAR;
typedef signed short SHORT;
typedef signed long LONG;

typedef unsigned char BYTE;
typedef unsigned short SWORD;
typedef unsigned long WORD;

//Macros
#define RGB16(r,g,b) ((r)+(g<<5)+(b<<10)) //Returns 15bit RGB value. 0>= rgb <=31
#define SetMode(mode) REG_DISPCNT = (mode)

#endif

4 - Finalmente hay que picarse un main.c que cargue los bytes de la imagen en la variable "ScreenBuffer" y listo.


/*
author: jduranmaster
*/

#include "base.h"
#include "flcl.h"

USHORT* ScreenBuffer = (USHORT*)0x6000000;

int main(){
USHORT loop;

SetMode(MODE3 | BG2_ENABLE);//seleccionamos el modo gráfico (MODO 3)

for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sampledata[loop];
}

//con el bucle cargamos en el buffer de pantalla los datos de la imagen.

while(1){}
}//fin de main

espero que os mole (es un ejemplo chorra pero ha quedado bien.:D)

xzakox
14/06/2010, 11:24
Muy buena la imagen de ejemplo jduranmaster xDD

Por mi parte he decidido empezar un tutorial de programación para la GameBoy en ensamblador en castellano, intentaré hacerlo lo más sencillo posible, usando las herramientas más modernas disponibles (rgbds, etc).

De momento estoy haciendo una introducción técnica a la GameBoy, si lo podeis leer y decirme si os parece claro y bien explicado, me hariais un favor. (Tener en cuenta que es un curso de ensamblador, asumo conocimientos básicos de programación, arquitectura de computadores, sistemas de numeración, etc).

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

jduranmaster
14/06/2010, 11:30
Muy buena la imagen de ejemplo jduranmaster xDD

Por mi parte he decidido empezar un tutorial de programación para la GameBoy en ensamblador en castellano, intentaré hacerlo lo más sencillo posible, usando las herramientas más modernas disponibles (rgbds, etc).

De momento estoy haciendo una introducción técnica a la GameBoy, si lo podeis leer y decirme si os parece claro y bien explicado, me hariais un favor. (Tener en cuenta que es un curso de ensamblador, asumo conocimientos básicos de programación, arquitectura de computadores, sistemas de numeración, etc).

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

ahora estoy preparando 3 ejemplitos nuevos:

EJ1 - Permite manejar las teclas de GBA de tal forma que se pueda cambiar de imagen.

EJ2 - Permite cargar una imagen en pantalla a la vez aque se escucha una melodia de fondo.

EJ3 - Combinación de los dos anteriores. Es decir cambiar de imagen mientras suena una melodia de fondo.

Me parece genial la idea del tuto de ensamblador de para GB, ahora cuando tenga un ratito me meto en el enlace y te dejo por aqui mis comentarios. Yo de ensamblador he realizado trabajos para la arquitectura 8086 de Intel (y todos sus derivados 386, 486, Pentium.... pues todos estos no son más que un 8086 primitivo pero con más registros memoria y demás) y tmb para un microcontrolador 80552 que si no recuerdo mal era un evolución del z-80, sin embargo este no lo recuerdo bien.

tSuKiYoMi
14/06/2010, 11:52
un ejemplo muy chulo jduran. voy a intentar reproducirlo a ver si lo consigo. has dicho que lo has hecho con el devkitadv, no? seria tmb reproducible con el devkitPRO???.

xzakox he leido el tutorial, yo la verdad tengo más experiencia programamando en C , asi que espero aprender bastantes cosas. muy buena iniciativa man!!!

3L_S4N70
14/06/2010, 12:13
Muy buena la imagen de ejemplo jduranmaster xDD

Por mi parte he decidido empezar un tutorial de programación para la GameBoy en ensamblador en castellano, intentaré hacerlo lo más sencillo posible, usando las herramientas más modernas disponibles (rgbds, etc).

De momento estoy haciendo una introducción técnica a la GameBoy, si lo podeis leer y decirme si os parece claro y bien explicado, me hariais un favor. (Tener en cuenta que es un curso de ensamblador, asumo conocimientos básicos de programación, arquitectura de computadores, sistemas de numeración, etc).

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Yo te animo con ese tuto. :D

Un saludo

FlipFlopX
14/06/2010, 12:29
Fantástico hilo, esto necesita chincheta

jduranmaster
14/06/2010, 12:34
Fantástico hilo, esto necesita chincheta

gracias a todos por los apoyos. y no dudeis en hacer vuestras propias pruebas y subir los resultados. Ahora que hemos puestos los enlaces pertienentes para la descarga de los devkits no teneis excusas.

Yo por mi parte creo que me dará tiempo a subir hoy dos nuevos ejemplos completos.

también creo que voy a editar el post primero para incluir en el todos los enlaces nuevos e información técnica sobre la GBA. No dudeis tmb en leeros el nuevo tuto de ensamblador para GB de xzakox (yo acabo de terminar de leerlo) y aunque todavía está en sus incios tiene uy buena pinta (de momento tiene info técnica sobre la GB).

Saludos.:awesome:

tSuKiYoMi
14/06/2010, 12:58
actualiza, actualiza xDD:awesome:

xzakox
14/06/2010, 13:31
El tuto está actualizandose sin parar eh xD
Enseguida termino con los registros básicos de la gameboy, y empiezo con el ensablador y un hola mundo :-)

jduranmaster
14/06/2010, 13:37
muy grande xzakox. Asi la gente puede visitar tu enlace y postear por aqui sus pequeñas obras. Estoy actualizando el post incial para incluir nueva información (tmb el enlace a tu página).

tSuKiYoMi
14/06/2010, 14:12
espero con ganas ese tuto en ensamblador para GB. por cierto para poder usar los conocimientos adquiridos era necesario el RGBDK, no? hay algun enlace por ahi para poder acceder a el?

Ñuño Martínez
14/06/2010, 14:16
Justo ahora que tengo un carchuto recauchutable, me viene de perilla. Gracias. :D

jduranmaster
14/06/2010, 14:29
Aqui ando de nuevo con otro ejemplo. En este caso se trata de una rom para GBA desarrollada con el devkitadv-r5-beta-3 que carga varias imagenes y permite al usuario ir navegando a través de ellas pulsando cualquiera de los diez botones de la consola.

Esta vez ha sido necesario incluir el fichero keypad.h donde se encuentran recodigas las corrrespondencias con los botones de la GameBoy Advance. el fichero keypad.h de la distribución del devkitadv es el siguiente:


//Key Definitions from Nokturn's key demo
#define KEY_A 1
#define KEY_B 2
#define KEY_SELECT 4
#define KEY_START 8
#define KEY_RIGHT 16
#define KEY_LEFT 32
#define KEY_UP 64
#define KEY_DOWN 128
#define KEY_R 256
#define KEY_L 512
int* KEYS = (int*)0x04000130;


una vez incluido este fichero en la carpeta de trabajo junto con el base.h que tmb usabamos en el ejmplo anterior y que recoge la definición del tipo USHORT empleado en las conversiones del PCX2GBA, solo nos queda mapear las imagenes con dicho programa a los correspondientes ficheros .h y generar el programa con el código principal que nos queda como sigue:


/*
author: jduranmaster
*/

#include "keypad.h" //definiciones del keypad.
#include "base.h" //definiciones de los tipos de datos que usa el devkitadv.
#include "flcl.h" //bytes de la imagen 1 obtenidos con la herramienta PCX2GBA.
#include "flcl1.h" //bytes de la imagen 2 obtenidos con la herramienta PCX2GBA.
#include "flcl2.h" //bytes de la imagen 3 obtenidos con la herramienta PCX2GBA.
#include "flcl3.h" //bytes de la imagen 4 obtenidos con la herramienta PCX2GBA.
#include "flcl4.h" //bytes de la imagen 5 obtenidos con la herramienta PCX2GBA.
#include "flcl5.h" //bytes de la imagen 6 obtenidos con la herramienta PCX2GBA.
#include "flcl6.h" //bytes de la imagen 7 obtenidos con la herramienta PCX2GBA.
#include "flcl7.h" //bytes de la imagen 8 obtenidos con la herramienta PCX2GBA.
#include "flcl8.h" //bytes de la imagen 9 obtenidos con la herramienta PCX2GBA.
#include "flcl9.h" //bytes de la imagen 10 obtenidos con la herramienta PCX2GBA.
#include "flcl10.h" //bytes de la imagen 11 obtenidos con la herramienta PCX2GBA.

USHORT* ScreenBuffer = (USHORT*)0x6000000;

int main(){
USHORT loop;

SetMode(MODE3 | BG2_ENABLE);//seleccionamos el modo gráfico (MODO 3)

//fijamos la imagen que aparecerá cuando se cargue la ROM por primera vez.
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample0data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.

while (1) // bucle infinito
{
// process input
if(!((*KEYS) & KEY_A)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample1data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_B)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample3data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_SELECT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample5data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_START)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample2data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_R)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample4data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_L)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample6data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_UP)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample7data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_DOWN)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample9data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_LEFT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample10data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_RIGHT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sample8data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
}
}//fin de main


el resultado como siempre lo podeis comprobar vosotros mismos usando el VisualBoy Advance. Agradecría que alguien pudiese probar las roms que voy subiendo por aqui en un flashcart para GBA y me diga que tal van en la maquina original. SALUDOS.:awesome:

otto_xd
14/06/2010, 14:54
Muy buena la imagen de ejemplo jduranmaster xDD

Por mi parte he decidido empezar un tutorial de programación para la GameBoy en ensamblador en castellano, intentaré hacerlo lo más sencillo posible, usando las herramientas más modernas disponibles (rgbds, etc).

De momento estoy haciendo una introducción técnica a la GameBoy, si lo podeis leer y decirme si os parece claro y bien explicado, me hariais un favor. (Tener en cuenta que es un curso de ensamblador, asumo conocimientos básicos de programación, arquitectura de computadores, sistemas de numeración, etc).

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

La verdad es que me ha gustado mucho, y mira que no se muchisimo de ensamblador y de arquitectura de ordenadores, pero esta claro claro ;)

Porcierto, muy interesante las propiedades de los sprites ^^

xzakox
14/06/2010, 16:35
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Echadle un vistazo, he añadido las herramientas para descargar y ya hay un hola mundo que podeis ensamblar y ejecutar, explicado con comentarios, después lo iré explicando paso a paso con cada instrucción de ensamblador. Por hoy ya vale xD

jduranmaster
14/06/2010, 16:40
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Echadle un vistazo, he añadido las herramientas para descargar y ya hay un hola mundo que podeis ensamblar y ejecutar, explicado con comentarios, después lo iré explicando paso a paso con cada instrucción de ensamblador. Por hoy ya vale xD

ok xzakox. gracias por el curro. En el primer post de este hilo tmb he añadido el enlace a tu página de GB. según vaya probadno seguiré subiendo más programas de ejemplo.

saludos.

jduranmaster
14/06/2010, 18:36
Continuamos con otro ejemplo que hace uso del modo 3 de GBA para pintar la pantalla de un color concreto. El ejemplo esta tmb realizado con el devkitadv-r5-beta-3.

en este caso me he tenido que definir un fichero denominado screenmode.h donde he definido todas las ctes necesarias para el manejo de los fondos de pantalla:


/*
author: jduranmaster
*/

#ifndef SCREENMODE_H
#define SCREENMODE_H

/////definicion del REG_DISPCNT

#define MODE_0 0x0
#define MODE_1 0x1
#define MODE_2 0x2
#define MODE_3 0x3
#define MODE_4 0x4
#define MODE_5 0x5

#define BACKBUFFER 0x10
#define H_BLANK_OAM 0x20

#define OBJ_MAP_2D 0x0
#define OBJ_MAP_1D 0x40

#define FORCE_BLANK 0x80

#define BG0_ENABLE 0x100
#define BG1_ENABLE 0x200
#define BG2_ENABLE 0x400
#define BG3_ENABLE 0x800
#define OBJ_ENABLE 0x1000
#define WIN1_ENABLE 0x2000
#define WIN2_ENABLE 0x4000
#define WINOBJ_ENABLE 0x8000

#define SetMode(mode) REG_DISPCNT = (mode)
#endif

también he utilizado otro fichero de cabecera llamado "gba.h" que contiene mas definicones de tipos auxiliares.


// gba.h by eloist

#ifndef GBA_HEADER
#define GBA_HEADER

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

typedef signed char s8;
typedef signed short s16;
typedef signed long s32;

typedef unsigned char byte;
typedef unsigned short hword;
typedef unsigned long word;

typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16;
typedef volatile unsigned long vu32;

typedef volatile signed char vs8;
typedef volatile signed short vs16;
typedef volatile signed long vs32;

typedef void (*fp)(void);

#define RGB16(r,g,b) ((r)+(g<<5)+(b<<10))

#define OAMMem ((u32*)0x7000000)
#define VideoBuffer ((u16*)0x6000000)
#define OAMData ((u16*)0x6010000)
#define BGPaletteMem ((u16*)0x5000000)
#define OBJPaletteMem ((u16*)0x5000200)

#define REG_DISPCNT *(vu32*)0x4000000
#define REG_VCOUNT *(vu16*)0x4000006

#define MODE_0 0x0
#define MODE_1 0x1
#define MODE_2 0x2
#define MODE_3 0x3
#define MODE_4 0x4
#define MODE_5 0x5

#define BACKBUFFER 0x10
#define H_BLANK_OAM 0x20

#define OBJ_MAP_2D 0x0
#define OBJ_MAP_1D 0x40

#define FORCE_BLANK 0x80

#define BG0_ENABLE 0x100
#define BG1_ENABLE 0x200
#define BG2_ENABLE 0x400
#define BG3_ENABLE 0x800
#define OBJ_ENABLE 0x1000

#define WIN1_ENABLE 0x2000
#define WIN2_ENABLE 0x4000
#define WINOBJ_ENABLE 0x8000

///////SetMode Macro
#define SetMode(mode) REG_DISPCNT = (mode)

#endif

y finalmente el código fuente del programa principal:


/*
author: jduranmaster
*/

#include "gba.h"
#include "screenmode.h"

#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))
#define BGR(b,g,r) ((r)+(g<<5)+(b<<10))

typedef u16 unsigned short int;

u16* videoBuffer = (u16*)0x6000000; //dirección de comienzo de la memoria de video.

void PlotPixel (int x, int y, unsigned short int c){videoBuffer[(y)*240 + (x)] = (c);}

int main(void){

int x,y;
SetMode(MODE_3 | BG2_ENABLE);//inicializamos con el MODO 3 de GBA y permitimos el background 2
for(x = 0; x < 240; x++){
for(y = 0; y < 160; y++){
PlotPixel(x,y,RGB(31,0,0));//pintamos el pixel por pantalla
}
}

while(1){}//bucle infinito

}//fin de main

espero que os sirva para dar los primeros pasos en la programación de GBA. Este programa esta testeado con VisualBoy Advance.

xzakox
14/06/2010, 18:39
Bueno, estoy añadiendo las primeras explicaciones al código del hola mundo, si podeis ir leyéndolo... más que nada para saber si se entiende bien, o tengo que mejorar las explicaciones, (o si creeis que me paso explicando) xD
Gracias.
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

jduranmaster
14/06/2010, 18:39
Bueno, estoy añadiendo las primeras explicaciones al código del hola mundo, si podeis ir leyéndolo... más que nada para saber si se entiende bien, o tengo que mejorar las explicaciones, (o si creeis que me paso explicando) xD
Gracias.
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

gracias por el aviso. ahora en un ratillo lo miro e intento probarlo.

jduranmaster
14/06/2010, 19:16
Y termino con otro ejemplo desarrollado con el devkitadv-r5-beta-3 para GBA que nos permite conmutar entre colores de pantalla y una imagen predefinida e integrada mediante el PCX2GBA. La conmutación se realiza mediante el uso del keypad.h que como ocurria en uno de los ejemplos anteriores tiene las constantes precisas para mapear los botones (en este ejemplo los botones que reciben los eventos son A, B, R y L). El código fuente del programa principal es:


/*
author: jduranmaster
*/

#include "gba.h"
#include "screenmode.h"
#include "keypad.h"
#include "base.h"
#include "flcl.h"

#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))
#define BGR(b,g,r) ((r)+(g<<5)+(b<<10))

typedef u16 unsigned short int;

USHORT* ScreenBuffer = (USHORT*)0x6000000;
u16* videoBuffer = (u16*)0x6000000; //dirección de comienzo de la memoria de video.

void PlotPixel (int x, int y, unsigned short int c){videoBuffer[(y)*240 + (x)] = (c);}

int main(void){

int x,y;
SetMode(MODE_3 | BG2_ENABLE);//inicializamos con el MODO 3 de GBA y permitimos el background 2

USHORT loop;

for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sampledata[loop];
}

while(1){
if(!((*KEYS) & KEY_A)){
for(x = 0; x < 240; x++){
for(y = 0; y < 160; y++){
PlotPixel(x,y,RGB(31,0,0));//pintamos el pixel por pantalla
}
}
}
if(!((*KEYS) & KEY_B)){
for(x = 0; x < 240; x++){
for(y = 0; y < 160; y++){
PlotPixel(x,y,RGB(0,31,0));//pintamos el pixel por pantalla
}
}
}
if(!((*KEYS) & KEY_L)){
for(x = 0; x < 240; x++){
for(y = 0; y < 160; y++){
PlotPixel(x,y,RGB(0,0,31));//pintamos el pixel por pantalla
}
}
}
if(!((*KEYS) & KEY_R)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = sampledata[loop];
}
}
}//bucle infinito

}//fin de main

bueno pues esto es todo por hoy. Ahora estoy trabajando en dos programillas mediante el devkitPRO para GBA: uno que usa los tiles de GBA y otro que usa el apartado de sonido. Según vaya avanzando con ellos, los subire por aqui.SALUDOS.:awesome:

tSuKiYoMi
14/06/2010, 20:14
gracias jduran por los ejemplos para GBA, estan currados con el codigo fuente y todo. y tmb gracias xzakox por el tuto de ensamblador de GB, lo estoy leyendo y esta bastante bien explicado.:awesome:

jduranmaster
14/06/2010, 21:39
me mola bastante el tuto de ensamblador xzakox. muy explicativo, como tiene que ser.:awesome:

xzakox
14/06/2010, 22:46
He añadido una sección al inicio, que la verdad, no podía faltar, una pequeña explicación sobre la CPU de la gameboy, sus registros y demás, a ver que os parece.
Mañana seguiré explicando el hola mundo.

jduranmaster
14/06/2010, 22:50
He añadido una sección al inicio, que la verdad, no podía faltar, una pequeña explicación sobre la CPU de la gameboy, sus registros y demás, a ver que os parece.
Mañana seguiré explicando el hola mundo.

ok. la verdad es que pinta bastante bien el tutorial de GB. mañana creo que me pondre a hacer pruebas con el.

Segata Sanshiro
14/06/2010, 23:21
He añadido una sección al inicio, que la verdad, no podía faltar, una pequeña explicación sobre la CPU de la gameboy, sus registros y demás, a ver que os parece.
Mañana seguiré explicando el hola mundo.

Qué pasada de tuto, muchas gracias por el curro. Está genial tenerlo todo recogidito en una web, en vez de andar tomando cosas de un sitio y de otro.

Allen_S
14/06/2010, 23:24
Muy interesante el proyecto... quisiera saber si esta orientado a usarse con flashcarts, o tambien con emuladores como el caso de la PSP o WIZ.

Sería genial que se pudiera crear un reproductor de mp3 para GBA usando flashcart.

Mas tarde pruebo tus roms con mi EZ Flash IV, ya te contaré como me fue.
Animo con el proyecto.

jduranmaster
14/06/2010, 23:37
Muy interesante el proyecto... quisiera saber si esta orientado a usarse con flashcarts, o tambien con emuladores como el caso de la PSP o WIZ.

Sería genial que se pudiera crear un reproductor de mp3 para GBA usando flashcart.

Mas tarde pruebo tus roms con mi EZ Flash IV, ya te contaré como me fue.
Animo con el proyecto.

gracias por los animos. es principio el software desarrollado tanto para GBA como para GB que aqui se hace tiene por objetivo ser ejecutado en FlashCart correspondiente a cada maquina. Ya te anticipo que las roms de GBA que he ido generando estos dias no funcionan en el emu de Wiz (de hecho no conozco ningun HomeBrew que funcione en el emulador de GBA de Wiz ), es un tema de la cabecera de las roms creo, sin embargo en uno de los kits de desarrollo (concretamente en el devkitPRO) existe una utlidad llamada fixgba o algo asi que modifica las cabeceras de los ficheros .gba generados. en fin supongo que todo será cuestion de probar. Sin embargo creo que en una GBA si que sería capaz de hgacerlos funcionar. Espero los resultados de vuestras pruebas.SALUDOS.

jduranmaster
15/06/2010, 11:08
Aqui os presento otro ejemplo que hace uso del modo gráfico 3 de GBA realizado mediante el devkitadv-r5-beta-3. Es muy sencillito, y tiene por objetivo completar la información que ya teniamos hacerca de como manejar los fondos de pantalla en el modo bitmap. El ejemplo pinta tres regiones de distinto color y mediante los botones A y B del pad podemos cambiar su distribución. En este caso he tomado otros ficheros .h que vienen en la distribución del kit para la definición de tipos y demás datos, pero el keypad.h que nos permitia definir la correspondencia de teclas con el PAD de la GBA sigue siendo el mismo.

El código del programa del programa principal es el siguiente:


/*
@author: jduranmaster
*/

#include "gba.h"

int main(){

u8 x,y;

SetMode(MODE_3 | BG2_ENABLE);

for(y=0;y<160;y++){
for(x=0;x<240;x++){
FrontBuffer[(y*240)+x]=RGB(0, 31, 0);
}
}

for(y=20;y<140;y++){
for(x=20;x<220;x++){
FrontBuffer[(y*240)+x]=RGB(0, 0, 31);
}
}

for(y=40;y<120;y++){
for(x=60;x<180;x++){
FrontBuffer[(y*240)+x]=RGB(31, 0, 0);
}
}



while(1){
// process input
if(!((*KEYS) & KEY_A)){
for(y=0;y<160;y++){
for(x=0;x<240;x++){
FrontBuffer[(y*240)+x]=RGB(0, 31, 0);
}
}

for(y=20;y<140;y++){
for(x=20;x<220;x++){
FrontBuffer[(y*240)+x]=RGB(0, 0, 31);
}
}

for(y=40;y<120;y++){
for(x=60;x<180;x++){
FrontBuffer[(y*240)+x]=RGB(31, 0, 0);
}
}
}
if(!((*KEYS) & KEY_B)){
for(y=0;y<160;y++){
for(x=0;x<240;x++){
FrontBuffer[(y*240)+x]=RGB(0, 0, 31);
}
}

for(y=20;y<140;y++){
for(x=20;x<220;x++){
FrontBuffer[(y*240)+x]=RGB(31, 0, 0);
}
}

for(y=40;y<120;y++){
for(x=60;x<180;x++){
FrontBuffer[(y*240)+x]=RGB(0, 31, 0);
}
}
}

}

return 0;

}//fin de main

xzakox
15/06/2010, 13:10
Ale, he terminado la primera parte del tutorial, el hola mundo completamente explicado, y he añadido un segundo programa con una mejorilla para evitar el problema de no inicializar la memoria de video.

Ya me comentais que os parece, para el próximo capítulo, sprites.
:-)

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

GameMaster
15/06/2010, 13:15
xzakox revisa tus links de downloads en el tuto que sólo sale el fetch.php :)

jduranmaster
15/06/2010, 13:17
genial el tuto completo. GameMaster tiene razón, revisa los enlaces de descarga que has puesto.

xzakox
15/06/2010, 13:50
Es muy raro, sale el fetch.php pero si lo descargas, es el archivo que debería ser.
Estoy mirando la configuración del wiki pero si quereis probar cosas, solo teneis que ir descargando y renombrando al nombre original que ponia el enlace.

jduranmaster
15/06/2010, 15:17
Aqui os traigo otro programita para la GBA realizado con el devkitadv-r5-beta-3. Se trata de una rom que usas sprites y el pad para permitir al usuario mover un cuadrado por la pantalla. Obviemente para su realización es necesario conocer un poco el modo de sprites que tiene la GBA. Dentro del devkitadv hay una documentación al respecto donde se explican los bits de los registros necesarios para manajar sprites y los modos asociados. que esto os sirva como ejemplo de lo que se podría hacer.

El código fuente del programa principal es el siguiente:


/*
@author: jduranmaster
*/

#include "gba.h"
#include "keypad.h"
#include "dispcnt.h"
#include "move.h"
#include "flcl.h"
#include "block1.h"

u16* OAM = (u16*)0x7000000;

//array de sprites.
OAMEntry sprites[128];

pRotData rotData = (pRotData)sprites;

//varaibles que marcan la posición de las coordenadas X e Y.
s16 xpos = 100;
s16 ypos = 60;

void CopyOAM(){
u16 loop;
u16* temp;
temp = (u16*)sprites;
for(loop = 0; loop < 128*4; loop++)
{
OAM[loop] = temp[loop];
}
}//fin de la función.

//inicializa los sprites en pantalla.
void InitializeSprites(){
u16 loop;
for(loop = 0; loop < 128; loop++)
{
sprites[loop].attribute0 = 160; //y to > 159
sprites[loop].attribute1 = 240; //x to > 239
}
}//fin de la función

//espera a que se termine de pintar en l pantalla.
void WaitForVsync(){
while((volatile u16)REG_VCOUNT != 160){}
}//fin de la función.

void GetInput(){
if(!(*KEYS & KEY_UP))
{
if(ypos > 0)
ypos--;
}
if(!(*KEYS & KEY_DOWN))
{
if(ypos < 144)
ypos++;
}
if(!(*KEYS & KEY_LEFT))
{
if(xpos > 0)
xpos--;
}
if(!(*KEYS & KEY_RIGHT))
{
if(xpos < 224)
xpos++;
}
if(!(*KEYS & KEY_A))
{}
if(!(*KEYS & KEY_B))
{}
if(!(*KEYS & KEY_L))
{}
if(!(*KEYS & KEY_R))
{}
if(!(*KEYS & KEY_SELECT))
{}
if(!(*KEYS & KEY_START))
{}
}//fin de la función.

//definir el sprite y pintarlo por pantalla.
void MoveSprite(OAMEntry* sp, int x, int y){
if(x < 0)
x = 512 + x;
if(y < 0)
y = 256 + y;

sp->attribute1 = sp->attribute1 & 0xFE00;
sp->attribute1 = sp->attribute1 | x;

sp->attribute0 = sp->attribute0 & 0xFF00;
sp->attribute0 = sp->attribute0 | y;
}//fin de la función.

int main(){
u16 loop;

SetMode(MODE_1 | OBJ_ENABLE | OBJ_MAP_1D); //modo 1 con mapeo 1D, además se permite el uso de sprites (OBJ_ENABLE)

//con el bucle cargamos en el buffer de pantalla los datos de la imagen.

for(loop = 0; loop < 256; loop++)
OBJPaletteMem[loop] = block1Palette[loop];

InitializeSprites();

sprites[0].attribute0 = COLOR_256 | SQUARE | ypos; //256 colores, con forma cuadrada y coordenada Y.
sprites[0].attribute1 = SIZE_16 | xpos; //tamaño del sprite 16x16 y coordenada X actual.
sprites[0].attribute2 = 0; //pointer to tile where sprite starts

for(loop = 0; loop < 128; loop++) //cargar el sprite.
{
OAMData[loop] = block1Data[loop];
}

while(1){//bucle infinito
GetInput();
MoveSprite(&sprites[0], xpos, ypos);
WaitForVsync();
CopyOAM();
}
}//fin de main.

En los posts espero poder subir ejemplos de manejo de sonido y animaciones. Aunque lo más probable es que ya sea usando el devkitPRO para GBA porque es más completo que el devkitadv. Un aspecto importante al respecto de esto es que el software para GBA desarrollado en un kit no es compatible con el otro (al menos eso ocurre entre el devkitadv y del devkitPRO), de todas formas como siempre al comienzo de cada post del hilo se especificará con que kit se realizó el ejemplo para que lo podais seguir bien. SALUDOS.:awesome:

tSuKiYoMi
15/06/2010, 15:21
un ejemplo muy bueno jduran.:awesome:

xzakox, estoy ahora con el tutorial de GB que has puesto en tu página. los ficheros para la compilación que has puesto (.bat) son los correctos?

xzakox
15/06/2010, 16:32
Si, acabo de probar todo en un windows XP y funciona correctamente, podeis descargar el assemble.bat de nuevo que he añadido una opción al rgbfix para que las roms queden mejor.

tSuKiYoMi
15/06/2010, 16:41
ok. voy a probar de nuevo.

xzakox
15/06/2010, 18:58
Bien, he añadido el código para un ejemplo con sprites y animación. Que lo disfruteis.

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

tSuKiYoMi
15/06/2010, 19:00
gracias tio. cuando obtenga progresos significativos los subire por aqui para compartirlos con la peña.

jduranmaster
15/06/2010, 19:04
Bien, he añadido el código para un ejemplo con sprites y animación. Que lo disfruteis.

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

gracias por el ejemplo nuevo tio. encuanto termine un par de ejelplos nuevos que estoy haciendo en GBA me pongo a mirar código para sacar algo de GB.:awesome:

jduranmaster
15/06/2010, 22:31
Aqui os dejo unas capturas de una rom curiosa que me he hecho (pesa demasiado como para subirla). Se trata de un video .avi convertido a rom .gba mediante una herramientra de conversión llamada METEO. Me ha parecido una herramienta cuento menos curiosa. Esta herramienta no viene junto con la distribución del devkitadv ni con la de devkitPRO. Asi que si a alguno de vosotros os interesa haceros con ella os recomiendo que os paseis por el gbadev , en esta página tiene un montón de herramientas empleadas para realizar desarrollos para GBA. Entre las más interesantes tenemos ya la ya conocida PCX2GBA, pero hay muchas más como GIF2SPRITE, PCX2SPRITE....... según vaya avanzando en lo desarrollos ire comentando la utilidad de cada una de ellas.SALUDOS.:awesome:.

GameMaster
15/06/2010, 23:31
En las demos que he puesto tambien hay videos hechos con herramientas similares, creo que venian con el kit, pero no me acuerdo cual era aunque me suena que era una version antigua del gbadev.

jduranmaster
16/06/2010, 11:02
la verdad es que me he quedado sorprendido de que existiera una herramienta como esa. y la verdad puede llegar a ser muy util.

< - >
una preguntailla xzabox, en el assemble.bat que nos has pasado se incluye la linea: command /c makelnk %1 > %1.lnk

pero creo que ese comando no le tengo: el makelnk, donde lo consigo?

xzakox
16/06/2010, 11:42
la verdad es que me he quedado sorprendido de que existiera una herramienta como esa. y la verdad puede llegar a ser muy util.

< - >
una preguntailla xzabox, en el assemble.bat que nos has pasado se incluye la linea: command /c makelnk %1 > %1.lnk

pero creo que ese comando no le tengo: el makelnk, donde lo consigo?

Es el otro .bat que hay que bajar, makelnk.bat ;)

jduranmaster
16/06/2010, 11:49
Es el otro .bat que hay que bajar, makelnk.bat ;)

@echo off
echo #autocreated Linkfile
echo #
echo #
echo [Objects]
echo %1.obj
echo #
echo [Output]
echo %1.gb

lo único que hace es sacar esos mensajes por pantalla?

xzakox
16/06/2010, 14:50
No, porque es llamado desde el archivo assemble.bat asi:

command /c makelnk %1 > %1.lnk

Con lo que crea el archivo nombre.lnk que usa el linker.

jduranmaster
16/06/2010, 14:53
No, porque es llamado desde el archivo assemble.bat asi:

command /c makelnk %1 > %1.lnk

Con lo que crea el archivo nombre.lnk que usa el linker.

podrías poner la linea de comandos de forma menos compleja?

es decir después de de ejecutar:

rgbasm95 -ohola.o hola.agb ya tendiriamos el fichero .o, y después de eso para o¡btener el .lnk, como sería?

xzakox
16/06/2010, 14:58
Pues necesitarias crear un fichero hola.lnk, con este contenido:

[Objects]
hola.obj
#
[Output]
hola.gb


Y entonces linkar con:
xlink95 -mmap hola.lnk

jduranmaster
16/06/2010, 15:01
Pues necesitarias crear un fichero hola.lnk, con este contenido:


Y entonces linkar con:
xlink95 -mmap hola.lnk

vale es decir el lnk es una especia e makefile (sencillito) donde especificas el fichero objeto y el fichero con el código. ok.

jduranmaster
16/06/2010, 15:07
ok, ya esta solucionado. el ejemplo tira. esta captura la he realizado con el VisualBoy Advance.:awesome:

jduranmaster
16/06/2010, 17:15
Aqui os presento el primer programa de ejemplo realizado para GBA usando el devkitPRO. Como comente en alguno de los posts anteriores el código generado con el devkitadv-r5-beta-3 no es compatible con el código generado con con el devkitPRO, entre otras cosas porque usan librerias diferentes para gestionar la memoria, acceso a teclado, pantalla, etc. El ejemplo que os presento es tan sencillo como el holaMundo de toda la vida. Pero así podeís apreciar la diferencia entre ambos kits, y la facilidad que ofrece el devkitPRO con respecto al devkitadv a la hora de formatear la salida. El código fuente del programa principal es el siguiente:


/*
@author jduranmaster. Tutorial 1 para devkitPRO. GBA.
*/

#include <gba_console.h>
#include <gba_video.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
#include <stdlib.h>

//---------------------------------------------------------------------------------
// INICIO DE PROGRAMA. Tutorial de programación para GameBoy Advance.
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------


irqInit();
irqEnable(IRQ_VBLANK);//el flag VBLANK debe estar activo, es necesario
//para que la función vBlankIntrWait tenga tiempo para pintar la pantalla.

consoleDemoInit();


// /x1b[linea;columuna
iprintf("\x1b[4;5H********************");
iprintf("\x1b[6;5HJduranMaster Says\n");
iprintf("\x1b[8;5HHello World!\n");
iprintf("\x1b[10;5H********************");
iprintf("\x1b[16;1HGameBoy Advance Tutorial.");

while (1) {
VBlankIntrWait();//espera a que se termine de pintar la pantalla.
}
}

como podeís ver la función principal que nos permite sacar texto por pantalla es iprintf(), esta función no se encuentra definida en el kit devkitadv. Se trata pués de una modificación de la función printf de C de toda la vida que tiene como parámetro adicional x1b[linea;columnaH donde podemos especificar en que linea y columna empezamos a escribir el texto deseado. Otro aspecto diferenciador, es la función VBlankIntrWait() wue espera a que se termine de pintar la pantalla, en elgunos ejemplos veremos que esta relacionado con el tema del vsync. Tmb podemos apreciar que los includes cambian bastante con respecto al devkitadv ya que el devkitpro incluye sus propias definiciones (y tengo que decir que son más completas que las del devkitadv.:D)

Un aspecto importante es que el devkitPRO trae integrado el Programmer´s NotePad como minientorno de desarrollo ya configurado para funcionar con MAkeFile´s customizados por el desarrollador. Otra opción que estuve probando estos días era integrar el compilador cruzado para el ARM7 de la GBA en el CodeBlocks y asi tener en el mismo entorno la posibilidad de hacer desarrollos para mis sistemas favoritos (Wiz, GP2X, NDS y GBA.). Si alguien está interesado puedo subir las capturas de pantalla donde se explican los pasos necesarios para configurar el codeblocks para tenerlo todo bien integrado.SALUDOS.:awesome:

tSuKiYoMi
16/06/2010, 21:42
otro gran ejemplo, me estoy bajando ahora el devkitPRO. en un rato pruebo a ver si lo consigo realizar. saludos.

_-Caleb-_
16/06/2010, 22:36
chicos mil disculpas, se me había pasado por completo este hilo :-) mañana me pongo a probar lo que váyais subiendo :-)

tSuKiYoMi
16/06/2010, 22:47
a mi tmb me gustaria probar en el flashcart de GBA pero no tengo aqui la consola (dita sea.)

_-Caleb-_
17/06/2010, 00:07
Yo la tengo, lo que no se es donde anda la maleta del netbook con el adaptador de tarjetas (Estamos de reformas xD)

pero en cuanto lo enuentre me pongo manos a la obra :D

Por cierto, mirando gbadev me he encontrado con esto: (http://www.gbadev.org/demos.php?showinfo=1279) que viene a ser un aliciente para que encuentre a la de YA el adaptador de la miniSD XDDD

tSuKiYoMi
17/06/2010, 09:54
Yo la tengo, lo que no se es donde anda la maleta del netbook con el adaptador de tarjetas (Estamos de reformas xD)

pero en cuanto lo enuentre me pongo manos a la obra :D

Por cierto, mirando gbadev me he encontrado con esto: (http://www.gbadev.org/demos.php?showinfo=1279) que viene a ser un aliciente para que encuentre a la de YA el adaptador de la miniSD XDDD

que grande una conversión del Another World a GBA, fantastico.:awesome:

jduranmaster
17/06/2010, 10:09
un Remake de Another World? buenisismo.:awesome:

saucjedi
17/06/2010, 10:27
Lo del Another World en GBA tiene tiempo ya, colegas

jduranmaster
17/06/2010, 10:33
Lo del Another World en GBA tiene tiempo ya, colegas

yo me acabo de enterar. Lo habeis probado?, yo lo estaba probando ahora en el VisualBoy Advance. Por cierto tienes MP

jduranmaster
17/06/2010, 11:12
Acabo de probar el ejemplo de xzakox de Hola Sprite y funciona bastante ben.

TEngo una duda con los MApa de Tiles, a ver si me la puedes resolver: en el tuto parace lo siguiente:




Tile: Datos:

.33333.. %01111100 %01111100 -- $7C $7C (Hex)
22...22. %11000110 %00000000 -- $C6 $00
11...11. %00000000 %11000110 -- $00 $C6
2222222. <-- los digitos %11111110 %00000000 -- $FE $00
33...33. representan %11000110 %11000110 -- $C6 $C6
22...22. los colores %11000110 %00000000 -- $C6 $00
11...11. %00000000 %11000110 -- $00 $C6
........ %00000000 %00000000 -- $00 $00




no entiendo bien la correspondencia que haces (por ejemplo) entre la linea 1 con su correspondiente especificación en binario:


.33333.. --> %01111100 %01111100

saludos.:awesome:

saucjedi
17/06/2010, 11:33
yo me acabo de enterar. Lo habeis probado?, yo lo estaba probando ahora en el VisualBoy Advance. Por cierto tienes MP

Lo llevo en el EzFlash IV desde hace la tira y es un vicio (jugué el original en su día y me enganché). Leí el MP pero no he pisado casa en dos días. Hoy ya toca, que ya iba siendo hora.

Habría que portar Flashback... otro grande de la época.

xzakox
17/06/2010, 12:05
.33333.. --> %01111100 %01111100

Como dice en el tuto:

De los dos bytes de cada línea (esto se complica un poco), el primer byte, recibe los bits menos significativos del color de cada pixel, y el segundo byte los más significativos, siendo el bit 7 el pixel de más a la izquierda, y el 0 el pixel de más a la derecha; eso es, si el primer pixel es gris oscuro (10) el bit 7 del primer byte será 1 y el bit 7 del segundo byte será cero.

Pues en el caso de esa linea. Cada linea dos bytes, ¿correcto? Entonces, primer pixel, blanco (.), color 0, en binario 00, por lo tanto el bit 7 del primer byte será 0, y el bit 7 del segundo byte, será 0. Luego viene el color 3. en binario 11, con lo que el bit 6 del primer byte será 1, y el bit 6 del segundo byte, será 1, Luego otro 3 (11), bit 5 del primer byte 1, bit 5 del segundo byte 1... etc, hasta completar los 8 pixeles de la linea, y con ellos los 8 bits de los dos bytes de cada linea.
¿Se entiende?

jduranmaster
17/06/2010, 12:09
.33333.. --> %01111100 %01111100

Como dice en el tuto:


Pues en el caso de esa linea. Cada linea dos bytes, ¿correcto? Entonces, primer pixel, blanco (.), color 0, en binario 00, por lo tanto el bit 7 del primer byte será 0, y el bit 7 del segundo byte, será 0. Luego viene el color 3. en binario 11, con lo que el bit 6 del primer byte será 1, y el bit 6 del segundo byte, será 1, Luego otro 3 (11), bit 5 del primer byte 1, bit 5 del segundo byte 1... etc, hasta completar los 8 pixeles de la linea, y con ellos los 8 bits de los dos bytes de cada linea.
¿Se entiende?

vale a hora esta todo correcto.los colores por tanto eran:


0 --> blanco.
1 --> gris claro.
2 --> gris oscuro
3 --> negro.

correcto?

xzakox
17/06/2010, 12:13
vale a hora esta todo correcto.los colores por tanto eran:


0 --> blanco.
1 --> gris claro.
2 --> gris oscuro
3 --> negro.

correcto?

Si, porque cuando metimos la paleta en memoria, lo hicimos asi:


ld a, %11100100 ; Colores de paleta desde el mas oscuro al
; más claro, 11 10 01 00
ld [rBGP], a ; escribimos esto en el registro de paleta


Pero podemos crear otra paleta tal que %10001101, con lo que tendriamos

0 - gris claro
1 - negro
2 - blanco
3 - gris oscuro

:-)

jduranmaster
17/06/2010, 13:08
Si, porque cuando metimos la paleta en memoria, lo hicimos asi:


ld a, %11100100 ; Colores de paleta desde el mas oscuro al
; más claro, 11 10 01 00
ld [rBGP], a ; escribimos esto en el registro de paleta


Pero podemos crear otra paleta tal que %10001101, con lo que tendriamos

0 - gris claro
1 - negro
2 - blanco
3 - gris oscuro

:-)


ok perfect. ahora me ha quedado mucho más claro. seguire haciendo pruebas. Espero que actualices pronto el tuto de GB.:awesome:

< - >
como podemos combinar varios tiles para hacer sprites más grandes?

GameMaster
17/06/2010, 13:11
Probad un juego indi llamado MEGATROID

http://gbax.gp2x.de/resultsimages/megatroid.png

jduranmaster
17/06/2010, 13:16
Probad un juego indi llamado MEGATROID

http://gbax.gp2x.de/resultsimages/megatroid.png

esta en la página del gbadev?

GameMaster
17/06/2010, 13:54
Pues no tengo ni idea, lo probe hace años y busque la foto por google. Vamos pongo en google que sale a la primera.

jduranmaster
17/06/2010, 14:00
ok voy a buscarlo. los gráficos que aparecen en la foto no tienen mala pinta.

GameMaster
17/06/2010, 14:02
Es sencillo pero lo bueno es su jugabilidad, las paredes se desintegran y tienes que meterte en los agujeros correctos para llegar al final de cada fase.

jduranmaster
17/06/2010, 15:00
si, ya lo encontre no esta mal.

xzakox
17/06/2010, 15:41
como podemos combinar varios tiles para hacer sprites más grandes?

Pues a mano, creando varios sprites, y moviendolos en conjunto.

He actualizado el tutorial, con manejo del pad y botones, y programa de ejemplo.

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Un saludo.

jduranmaster
17/06/2010, 15:52
Pues a mano, creando varios sprites, y moviendolos en conjunto.

He actualizado el tutorial, con manejo del pad y botones, y programa de ejemplo.

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Un saludo.

muchas gracias.:awesome:

GameMaster
17/06/2010, 16:09
Thanks bro, la verdad estais haciendo todos un explendido trabajo, sólo no vuelto a trastear con esto porque estoy liado con otras cosillas, y cuando vuelva a perder tiempo con algo similar será con el SDK de Mega Drive :)

jduranmaster
17/06/2010, 16:10
Thanks bro, la verdad estais haciendo todos un explendido trabajo, sólo no vuelto a trastear con esto porque estoy liado con otras cosillas, y cuando vuelva a perder tiempo con algo similar será con el SDK de Mega Drive :)


yo lo tengo bajado tmb el SDK de MEgaDrive. Cuando tengas tiempo abre un hilo. Estaré encantado de contribuir con algo.

GameMaster
17/06/2010, 16:14
yo lo tengo bajado tmb el SDK de MEgaDrive. Cuando tengas tiempo abre un hilo. Estaré encantado de contribuir con algo.

A ver si consigo recuperar lo que tenia en mi HD cuando tenga tiempo, y despues me pongo con algo :brindis:

http://www.gp32spain.com/foros/showthread.php?t=72205&highlight=mega+drive+basic

jduranmaster
17/06/2010, 16:22
A ver si consigo recuperar lo que tenia en mi HD cuando tenga tiempo, y despues me pongo con algo :brindis:

http://www.gp32spain.com/foros/showthread.php?t=72205&highlight=mega+drive+basic

joer, no me acordaba de este hilo.:D

saucjedi
17/06/2010, 17:17
Thanks bro, la verdad estais haciendo todos un explendido trabajo, sólo no vuelto a trastear con esto porque estoy liado con otras cosillas, y cuando vuelva a perder tiempo con algo similar será con el SDK de Mega Drive :)

Si a aprender y ejercitar un poco la materia gris lo llamas perder tiempo...

jduranmaster
17/06/2010, 17:20
creo que lo dice metaforicamente. en el fondo le mola.......:awesome:

GameMaster
17/06/2010, 17:47
Si a aprender y ejercitar un poco la materia gris lo llamas perder tiempo...

:D No se os escapa nada.

jduranmaster
18/06/2010, 11:15
YOOHOHOO, ya tengo mi FlashCart para GBA para realizar las pruebas. ahora os comento que tal ha ido la cosa.:awesome:

GameMaster
18/06/2010, 11:19
En principio todas las demos tienen que chutar.

jduranmaster
18/06/2010, 12:11
En principio todas las demos tienen que chutar.

y lo que no sean demos tmb. ahora os comento.

< - >
bueno he probado y la mayortia del HomeBrew de ejemplos que he estado haciendo estos dias funciona sin problemas, solo he detectado errores en algunos programas de los que realice. Resulta que algunas roms cuando se cargan se quedan en la pantalla de presentación el que pone "GameBoy" y la palabra Nintendo sale borrosa. Eso es porque en esas roms no pase el gbafix , es decir a quella herramienta que formateaba correctamente la cabecera de la rom generada. PAra evitar problemas voy a pasar dicha herramienta por todo el material que he ido subiendo y a resubirlo para que aquellos que lo quieran probar no se lleven sorpresas.SALUDOS.:awesome:

jduranmaster
18/06/2010, 13:41
Hola a todos. Ya he resuelto el problema de las cabeceras en aquellas ROMS donde no habia pasado la utilidad GBAFIX. Ahora todas las roms deberían tirar sin problemas (de hecho lo hacen, al menos en mi GBA) usando un FlashCart en GBA. Lo que no he probado es hacerlas funcionar en el emu de Wiz. Si alguien se presta a probarlas se lo agrdecería mucho, pues ahora mismo no tengo la Wiz a mano como para poder probar. Lo dicho aqui os dejo un rar con todas las roms "fixeadas" (Real Academia de la Lengua, perdoname).SALUDOS.:awesome:

GameMaster
18/06/2010, 13:55
Karma Up!!!

jduranmaster
18/06/2010, 17:08
Ahora estaba probando el GOOMBA para GBA. Alguien sabe si es posible jugar a las ROMS aprovechando toda la pantalla de la GBA?. Lo pregunto porque por defecto no es posible escalar la pantalla y viene con un tamaño fijo.saludos.:awesome:

< - >
Bueno pues aqui os dejo un un programa que espero sirva para hacernos la vida más sencilla en los desarrollos. Si recordais para el manejo de imagenes tanto en el devkitPRO como con el devkitadv era necesario coger nuestra imagen en formato PCX y pasarla por el programa PCX2GBA para generar un fichero .h donde se especificaban los datos de la imagen en un tipo USHORT (unsigned short), bueno pue para facilitar esta tarea he desarrollado una herramienta en java que realiza esta función (asi tenemos varias posibilidades de realizar las conversiones). LA herramienta de momento no salva en un fichero .h sino que lo construye y lo muestra por consola. (ahora mismo estoy trabajando en la versión que salve directamente la info que nos interesa en un fichero .h de C).

El código del programa es:



/*
@author: jduranmaster
*/
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;

import java.io.FileInputStream;
import java.io.InputStream;

import javax.imageio.ImageIO;

public class HGenerator{
public static final int PIXEL_ROW_WIDTH = 40;

public static void main(String[] args) {
try
{
String prefix = "exptiles";
if (args.length > 1)
prefix = args[1];
InputStream is = new FileInputStream(args[0]);
BufferedImage img = ImageIO.read(is);
System.out.println("/*HGenerator Tool */");
System.out.println();
System.out.println("#define " + prefix + "_WIDTH " + img.getWidth());
System.out.println("#define " + prefix + "_HEIGHT " + img.getHeight());
System.out.println();
if (img.getType() == BufferedImage.TYPE_BYTE_INDEXED)
{
System.out.println("/* Es una imagen de 256 colores. */");
ColorModel m = img.getColorModel();
// Obtenemos los valores de la paleta
System.out.println("const u16 " + prefix + "Palette[] = {");
for (int i = 0; i < 256; i++)
{
int red = (m.getRed(i) >> 3);
int green = (m.getGreen(i) >> 3);
int blue = (m.getBlue(i) >> 3);
short rgb = (short) (red | (green << 5) | (blue << 10));
System.out.print("\t0x" + Integer.toHexString(rgb));
if (i < 255)
System.out.println(",");
}
System.out.println("};");
System.out.println();
// Y los valores de los pixels de la imagen
DataBuffer buffer = img.getData().getDataBuffer();
System.out.print("const u16 " + prefix + "Data[] = {");
int n = buffer.getSize();
for (int i = 0; i < n; i += 2)
{
if ((i % PIXEL_ROW_WIDTH) == 0)
System.out.println();
int pixel = (buffer.getElem(i) | (buffer.getElem(i + 1) << 8));
System.out.print("0x" + Integer.toHexString(pixel));
if (i < (n - 2))
System.out.print(", ");
}
System.out.println();
System.out.println("};");
}
else
{
System.out.println("/* No es una imagen de 256 colores. Dumpeando entradas RGB. */");
System.out.println("const u16 " + prefix + "Data[] = {");
int width = img.getWidth();
int height = img.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = img.getRGB(x, y);
int red = ((pixel >> 16) & 0x0000FF) >> 3;
int green = ((pixel >> 8) & 0x0000FF) >> 3;
int blue = (pixel & 0x0000FF) >> 3;
short rgb = (short) (red | (green << 5) | (blue << 10));
System.out.print("0x" + Integer.toHexString(rgb));
if ((x < (width - 1)) || (y < (height - 1)))
System.out.print(", ");
}
System.out.println();
}
System.out.println("};");
}
} catch (Exception e) {
System.err.println("Syntaxis: java HGenerator image_file [variable_name_prefix]");
}
}//fin del metodo main.
}//fin de la clase.


Cuando termine la nueva versión la subiré para que la tengais por aqui. SALUDOS.:awesome:

jduranmaster
18/06/2010, 17:10
Se me olvidaba subiros el código fuente, por si quereis probar directamente. Aqui lo teneis.:awesome:

xzakox
18/06/2010, 17:46
Actualizado el tutorial con un ejemplo jugoso, uso de la ventana, scroll del fondo, animación de un sprite de 16x16 (usando 4 de 8x8 juntos)... a ver que os parece:
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

jduranmaster
18/06/2010, 17:50
Actualizado el tutorial con un ejemplo jugoso, uso de la ventana, scroll del fondo, animación de un sprite de 16x16 (usando 4 de 8x8 juntos)... a ver que os parece:
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

gracias tio. Aun tengo que probar el anterior. Estaba intentando escribir un mensaje por pantalla usando varios tiles, pero me atasque. a ver si saco algo mas de tiempo y le doy a la GB.:awesome:

jduranmaster
18/06/2010, 17:58
Aqui os presento un nuevo ejemplo usando el devkitPRO, se trata de una rom que saca por pantalla un mensaje de texto animado. Ya he usado en esta rom el gbafix, por lo que no hay problema en las cabeceras y funciona correctamente en una gba con flashcart. El ejemplo esta realizado usando unas librerias y .h no oficiales llamados "TONC", que facilitan el tema de la animación. Aqui os pongo el código fuente como siempre del programa principal:




/*
@author: jduranmaster
*/

#include <tonc.h>
#include <tonc_Legacy.h>

#define L_TEXT_V11



// --------------------------------------------------------------------
// CONSTANTS & STRUCTS
// --------------------------------------------------------------------


#define POS0 (80<<8)
#define GRAV 0x40
#define DAMP 0xD0
#define HWLEN 12

const char hwstr[]= "JdUrAnMaStEr";

typedef struct
{
u32 state;
int tt;
FIXED fy;
FIXED fvy;
} PATTERN;


// --------------------------------------------------------------------
// FUNCTIONES
// --------------------------------------------------------------------


void pat_bounce(PATTERN *pat)
{
if(pat->tt <= 0) // el timer ha llegado al limite.
{
pat->fvy += GRAV;
pat->fy += pat->fvy;

// tocamos la raya amarilla.
if(pat->fy > POS0)
{
if(pat->fvy > DAMP)
{
pat->fy= 2*POS0-pat->fy;
pat->fvy= DAMP-pat->fvy;
}
else
{
pat->fy= POS0;
pat->fvy= 0;
}
}
}
else // aun no acaba la cuenta.
pat->tt--;
}

int main()
{
REG_DISPCNT= DCNT_MODE3 | DCNT_BG2 | DCNT_OBJ;

irq_init(NULL);
irq_add(II_VBLANK, NULL);
memset16(&vid_mem[88*240], CLR_GREEN, 240);

// texto inicial del sprite.
txt_init_std();
txt_init_obj(oam_mem, 0xF200, CLR_YELLOW, 0x0E);
gptxt->dx= 12;

// letras iniciales del sprite.
OBJ_ATTR *obj= oam_mem;
obj_puts2(120-12*HWLEN/2, 8, hwstr, 0xF200, obj);

int ii;
PATTERN pats[HWLEN];

for(ii=0; ii<HWLEN; ii++)
{
// valores iniciales.
pats[ii].state=0;
pats[ii].tt= 3*ii+1;
pats[ii].fy= -12<<8;
pats[ii].fvy= 0;

// posición inicial del sprite.
obj[ii].attr0 &= ~ATTR0_Y_MASK;
obj[ii].attr0 |= 160;
}

while(1)
{
VBlankIntrWait();//espera a que se haya pintado la pantalla.

for(ii=0; ii<HWLEN; ii++)
{
pat_bounce(&pats[ii]);

obj[ii].attr0 &= ~ATTR0_Y_MASK;
obj[ii].attr0 |= (pats[ii].fy>>8)& ATTR0_Y_MASK;
}
}

return 0;
}



Ahora estoy pegandome con los registros de sonido a ver si consigo hacer sonar ficheros midi y mod en la GBA. Asi que según vaya haciendo progresos lo comentare por aqui. SALUDOS.:awesome:

GameMaster
18/06/2010, 18:03
Estoy flipando contigo, a este ritmo en dos dias tendrias un juego listo para el concurso pero como no es para GBA, vas tan rapido que en 2 semanas igual ya tienes un juego para la 3ds :)

jduranmaster
18/06/2010, 18:09
Estoy flipando contigo, a este ritmo en dos dias tendrias un juego listo para el concurso pero como no es para GBA, vas tan rapido que en 2 semanas igual ya tienes un juego para la 3ds :)

jajajaja. venga ya. Tenia pensado presentar un juego en Bennu para el concurso de GP32Spain (de hecho sigo pensando hacerlo). Se trata de un shooter con gráficos prefabricados y alguno ripeado, lo que ocurre es que no se si me va a dar tiempo. El caso es que el tema de la GB y la GBA me mola tanto que estoy enganchadisimo. De todas formas sigo pensando en el juego en Bennu que quiero hacer y en otro con SDL+C que seguro que no me da tiempo ni de coña a presentarlo. Sin embargo aunque no me de tiempo puedes apostar a que cuando esten listos los subire de todas formas. no me mueve el dinero.:awesome:

GameMaster
18/06/2010, 18:20
Me alegra que el dinero no te mueva, por suerte hay mucha gente así, vamos si no fuera así no tendriamos la scene Gp32.
Venga, seguiré rebuscando por aqui tus nuevas demos :felicidades:

jduranmaster
18/06/2010, 18:26
Me alegra que el dinero no te mueva, por suerte hay mucha gente así, vamos si no fuera así no tendriamos la scene Gp32.
Venga, seguiré rebuscando por aqui tus nuevas demos :felicidades:

[ENSUCIANDO HILO: ON]

Hay alguna noticia nueva al respecto de OGRE3D para Bennu?

[ENSUCIANDO HILO: OFF]

GameMaster
18/06/2010, 18:38
El engine 3D sigue, pasate por el foro de Bennu para más detalles, pero con lo que hay ya tienes de sobra para empezar, tienen muchos modelos y recursos.

jduranmaster
18/06/2010, 18:39
:awesome:ok. gracias por la info.

Segata Sanshiro
18/06/2010, 19:13
Por cierto, jduranmaster, ahora que lo pienso, mejor encierra el código con [code] [/ code], para que quede más bonito.

jduranmaster
18/06/2010, 20:07
Por cierto, jduranmaster, ahora que lo pienso, mejor encierra el código con [code] [/ code], para que quede más bonito.

te puedes creer que siempre se me olvida, es decir estoy escribiendo el post, e insitintivamente voy y meto el código en una etiqueta QUOTE.jejejeje. gracias por recordarmelo.:awesome:

< - >
pues rebuscando por la red, me he encontrado con una herramienta supercuriosa. Habiamos hablado del PCX2GBA que convertia una imagen en formato PCX en un fichero .h de lenguaje de programación C. Pues existe un programa similar llamado: wav2GBA que hace lo mismo pero con ficheros de audio con extensión WAV. Puede ser muy interesante famigos.:awesome:

otto_xd
18/06/2010, 20:14
Actualizado el tutorial con un ejemplo jugoso, uso de la ventana, scroll del fondo, animación de un sprite de 16x16 (usando 4 de 8x8 juntos)... a ver que os parece:
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador

Mu bueno!

A ver si termino y puedo hacer alguna cosilla ^^

Algun editor de tiles o de sprites que te de los valores hexadecimales para pegar en el codigo??Tal vez lo has puesto, asi que no te enfades si esta xD

swapd0
18/06/2010, 20:29
Si usas ensamblador puedes hacer el incbin del fichero y no necesitas convertirlo a valores hexadecimales.

En caso de C, suele haber un ejecutable llamado dat2obj o algo asi, para crear un fichero objeto de un fichero de datos, despues incluyes el fichero en el linkador y asunto solucionado.

jduranmaster
18/06/2010, 20:52
en la Web de GBADEV hay una rom muy interesante (*) llamada Jespa3D_1_39.gba, se trata de una adapatación del motor gráfico de Doom para GBA. Al que le interese le pongo dos capturas realizadas con el VisualBoy Advance.:awesome:

xzakox
19/06/2010, 09:19
Mu bueno!

A ver si termino y puedo hacer alguna cosilla ^^

Algun editor de tiles o de sprites que te de los valores hexadecimales para pegar en el codigo??Tal vez lo has puesto, asi que no te enfades si esta xD

No no dije nada xD, voy a añadirlos al tutorial. Yo uso el GBTD (Gameboy Tile Designer), y el GBMB (Gameboy Map Builder), podeis descargarlos de:
http://www.devrs.com/gb/hmgd/gbtd.html
http://www.devrs.com/gb/hmgd/gbmb.html

Son para windows, pero van perfectamente en wine (yo los uso en linux). Ahora comento en el tutorial como usarlos para generar datos.

EDIT: Ya teneis añadidas las explicaciones de como usarlos al final del último ejemplo.

jduranmaster
19/06/2010, 11:10
No no dije nada xD, voy a añadirlos al tutorial. Yo uso el GBTD (Gameboy Tile Designer), y el GBMB (Gameboy Map Builder), podeis descargarlos de:
http://www.devrs.com/gb/hmgd/gbtd.html
http://www.devrs.com/gb/hmgd/gbmb.html

Son para windows, pero van perfectamente en wine (yo los uso en linux). Ahora comento en el tutorial como usarlos para generar datos.

EDIT: Ya teneis añadidas las explicaciones de como usarlos al final del último ejemplo.

gracias por la actialización tio. De todas formas todas laas herramientas para hacer desarrollos para GBA asi como para GB tienen enlaces en el primer post de este hilo.SALUDOS.:awesome:

xzakox
19/06/2010, 14:38
Si, pero habia que explicar cómo usarlas :-)

jduranmaster
19/06/2010, 14:49
Si xDD.

jduranmaster
19/06/2010, 15:02
Bueno pues ha probado el JoyPad de xzakox y me ha quedado bastante claro, la verdad es que el tema de manejo de los botones no es complicado. Os dejo un par de capturillas con el resutlado.:awesome:

jduranmaster
19/06/2010, 15:37
Muy grande el ultimo ejemplo del tuto de xzabox, ya tenemos un Mario que anda y todo. Aqui dejo unas capturillas con el resultado.:awesome:. Voy a darle un rato al GBTD y al GBMB.SALUDOS.:awesome:

xzakox
19/06/2010, 16:23
Comparto este enlace con vosotros, el código completo tal y como se desarrolló del juego comercial MrDO! de GameBoy.

http://www.pauliehughes.com/page21/files/mrdo.asm

jduranmaster
19/06/2010, 16:25
Comparto este enlace con vosotros, el código completo tal y como se desarrolló del juego comercial MrDO! de GameBoy.

http://www.pauliehughes.com/page21/files/mrdo.asm

aplausos.:awesome:

xzakox
19/06/2010, 16:44
aplausos.:awesome:

Al coder original que ha compartido su código ;-)

jduranmaster
19/06/2010, 17:34
acabo de añadir en el primer POST del hilo un enlace a un tutorial básico sobre ensamblador para el ARM7 de la GBA.SALUDOS.:awesome:

jduranmaster
19/06/2010, 19:04
Aqui andamos de nuevo para comentar el tema de los editores para GBA. Hay dos herramientas muy interesantes para el desarrollo de gráficos y mapas.

- Para el desarrollo de mapas tenemos "MAPED" (primera captura) que permite la definición de mapas para GBA y es una herramienta muy completa en ese sentido. Si la quereis bajar podeis haceros con ella a través de la página oficial de GBADEV.

- Para el desarrollo de tiles tenemos varias herramientas imoprtantes, pero quiza la major de todas es "Tile Studio" (resto de capturas). Esta herramienta tiene todo lo necesario para definir Tiles y es muy completa. UNa vez que tenemos el fichero con los tiles salvado podemos exportar el resultado a multitud de lenguajes de programación, entre ellos C, C++, Java...... En el GBADEV la recomiendan frente a otras. La última versión es de 2008. Igualmente la podeis descargar via GBAdeV en donde encontrais un enlace a la página del autor en cuestión. PAra ahcer funcionar la últiam versión del "Tile Studio" es necesario bajarse la versión anterior (de 2006 creo) y luego bajarse el ejecutable de la versión de 2008 (que es lo único que cambia con respecto a la versión de 2006). Aqui os dejo un par de capturas para que veais como son.

Una última cosilla, si recordais en posts anteriores subí unas capturas de una ROM que me había bajado del GBADEV llamada JESPA_3D, y que se trata de una especie de motor 3D (bueno realmente serían 2.5D) del Doom. He estado seguiendo un tutorial del autor de dicha ROM, y proximamante podré subir los resultados al respecto. SALUDOS.:awesome:

jduranmaster
19/06/2010, 19:22
Bueno pues aqui os dejo mi primera ROM para GameBoy (es una chapuza lo sé, pero por algo se empieza). Es una simplificación del ejemplo de xzakox. En esta saco un monigote realizado con el editor de tiles para GBDK (el GBTD). Podemos mover al monigote por el borde inferior de la pantalla (es un único tile realizado en 2 minutos asi que no espereis que quede bonito). Aqui os dejo un par de capturas y la ROM por si alguien quiere probarla.SALUDOS.:awesome:

jduranmaster
19/06/2010, 20:50
Hace un par de dias comentabamos una herramienta llamada METEO que nos permitia convertir ficheros .avi a .gba para poder reproducir videos en la GBA. Ahora os subo un ejemplo de ROM (la otra vez no pude hacerlo porque aquella rom era damasiado grande). Aqui os dejo el resultado. SALUDOS.:awesome:

PD: una question relacionada con el ejemplo del mario xzakox, de que tamaño es el mario? 16x16?

jduranmaster
19/06/2010, 22:35
Me acabo de encontrar con un bombazo. El otro día comentabamos que había un port del Another Wolrd para GBA (buenisimo port cierto:awesome:). Alguien comentaba que sería genial tener un port de FlashBack para GBA y tenia mucha razón. Resulta que hay un gurpo de desarrolladores Franceses que se han currado la continuación de FlashBack titulada "FlashBack Legends". Se trata de un juego totalmente nuevo con gráficos ripeados del original y con gráficos nuevos para GBA. Os dejo la ROM y un par de capturas para que lo probies. Yo lo he estado testeando en el VisualBoy Advance porque no tengo tiempo ahora de probarlo en la GBA, si alguien tiene un momento que lo haga y lo pruebe en el FlashCart de GBA, en fin .... que lo disfruteis. SALUDOS.:awesome:

xzakox
20/06/2010, 00:18
PD: una question relacionada con el ejemplo del mario xzakox, de que tamaño es el mario? 16x16?

Si, son 4 sprites de 8x8.

PD: Acabo de encontrar una opción del ensamblador del RGBDS para guardar los datos de tiles en memoria de una manera muy sencilla.
Es simplemente usar DW (como visteis DB sirve para definir bytes de datos que se meterán en el programa final, pues DW son words, o dos bytes, y como sabeis cada linea de un tile son dos bytes) con una sintaxis especial, pero es tan sencillo como:



DW `01012323


Donde cada número es el color. Tan sencillo como eso. Asi para el tile de 8x8 de la cara sonriente del primer ejemplo simplemente podriamos definirlo asi:


DW `03333300
DW `31111130
DW `31010130
DW `31010130
DW `31111130
DW `30111030
DW `31000130
DW `03333300

jduranmaster
20/06/2010, 09:55
Si, son 4 sprites de 8x8.

PD: Acabo de encontrar una opción del ensamblador del RGBDS para guardar los datos de tiles en memoria de una manera muy sencilla.
Es simplemente usar DW (como visteis DB sirve para definir bytes de datos que se meterán en el programa final, pues DW son words, o dos bytes, y como sabeis cada linea de un tile son dos bytes) con una sintaxis especial, pero es tan sencillo como:



DW `01012323


Donde cada número es el color. Tan sencillo como eso. Asi para el tile de 8x8 de la cara sonriente del primer ejemplo simplemente podriamos definirlo asi:


DW `03333300
DW `31111130
DW `31010130
DW `31010130
DW `31111130
DW `30111030
DW `31000130
DW `03333300


pues si queda más sencillo usando WORDs. El tema es que el GBTD te lo genera como DB, se le puede indicar el programa que genere WORDs en lugar en de Bytes, o eso ya tendríamos que hacerlo nosotros de forma manual? SALUDOS.:awesome:

jduranmaster
20/06/2010, 14:18
Volvemos a la carga de nuevo con GBA. Esta vez os presento un proyecto basado en un tutorial realizado por el autor del JESPA_3D. Se trata de un minijuego donde el usuario puede caminar a traves de un escenario 3D (bueno.... realmente son 2.5D). El programa está realizado usando el devkitadv-r5-beta-3 (más que nada porque con el devkitPRO me parecia demasiado complejo el control de los botones del PAD y con el devkitADV esta resuleto de forma más sencilla, sin embargo no tendría que haber ningún problema en compilarlo con el devkitPRO.:awesome:). Como he comentado en el código del programa principal he utilizado un fichero .h, concretamente el trig.h que forma parte del proyecto original de JESPA_3D. En este fichero se encuentra definida una tabla con los puntos de coordenadas y angulos del mapa en el que nos podemos mover. El mapa por el cual nos podemos desplazar esta definido de la forma siguiente:




#define MAPWIDTH 16
#define MAPHEIGHT 16

const char fMap[]=
{// 0 5 10 15
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, // 0
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,O,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,O,W,W,O,W,O,O,O,W, // 5
W,O,O,O,O,O,W,O,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,W,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,O,W,O,O,O,W,O,O,O,W,
W,O,O,O,O,O,O,W,W,W,W,W,O,O,O,W,
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W, // 10
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W,
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W,
W,O,O,W,W,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, // 15
};



Como podeis observar W significa "MURO" (es una constante de valor 1), mientras que O significa "ESPACIO LIBRE", es decir el espacio por el cual podemos desplazrnos sin que haya ninguna colisión (es una constante de valor 0). Tmb comentar que este es el primer ejemplo serio en el que uso el modo gráfico 4 de la GBA (tiles), aunque ya tengo algunos ejemplos en mente donde le podremos sacar más partido. Tmb es importante recalcar que he usado los ficheros de cabecera gba.h, keypad.h y screenmode.h que defini y use en anteriores proyectos y ejemplos con el devkitadv. Aqui os pongo el programa principal del juego:




/*
--------------------------------------------------------------------
@author: jduranmaster
@title: jduranWolf.c
@versión: 1.0
************************************************** ******************
Parte de este proyecto está basado en el código original de JESPA_3D
Gracias al autor por subir el trig.h y compartir sus conocimientos
en el GBADEV.
************************************************** ******************
--------------------------------------------------------------------
*/

//----------------------------------------------------------------
// ficheros de cabecera incluidos.
//----------------------------------------------------------------
#include "gba.h" //definición de los registros de la GBA.
#include "keypad.h" //definición del PAD
#include "screenmode.h" //modos de pantalla --> basado en el tuto de Loriak
#include "trig.h" //trig lookup tables --> tomado del ejemplo de JESP_3D


//----------------------------------------------------------------
// constantes del programa.
//----------------------------------------------------------------
#define SCREENWIDTH 240 //ancho de nuestra pantalla.
#define SCREENHEIGHT 160 //alto de nuestra pantalla.
#define GRIDWIDTH 32
#define GRIDHEIGHT 32
#define PLAY_LENGTH (207.85)
#define W 1 // MURO.
#define O 0 // ESPACIO ABIERTO.
#define PI (3.14159) //el número PI.
#define SHORT_LINE 1200 // screenwidth/2 * 10
#define LONG_LINE 1800 // screenwidth/2 * 15
#define true 1
#define false 0

const u16 gPalette[] = { // 0..16
0x7203, 0x7205, 0x7208, 0x720A, 0x720D, 0x720F, 0x7212, 0x7214,
0x2945, 0x2946, 0x2948, 0x294A, 0x294C, 0x294E, 0x6B5A, 0x56B5,};

//--------------------------------------------------------------------------------------------------------------------------
// Este es el mapa usado. Lo podemos cambiar tranquilamente para crear nuestros propios escenarios. Como se puede ver,
// W significa "MURO" (#define W 1) y O significa "ESPACIO ABIERTO" (#define O 0 ). El Mapa es un cuadrado de 16x16.
//--------------------------------------------------------------------------------------------------------------------------
#define MAPWIDTH 16
#define MAPHEIGHT 16

const char fMap[]=
{// 0 5 10 15
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, // 0
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,O,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,O,W,W,O,W,O,O,O,W, // 5
W,O,O,O,O,O,W,O,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,W,W,W,O,O,W,O,O,O,W,
W,O,O,O,O,O,O,W,O,O,O,W,O,O,O,W,
W,O,O,O,O,O,O,W,W,W,W,W,O,O,O,W,
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W, // 10
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W,
W,O,W,O,O,W,O,O,O,O,O,O,O,O,O,W,
W,O,O,W,W,O,O,O,O,O,O,O,O,O,O,W,
W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W, // 15
};

//----------------------------------------------------------------
// variables globales.
//----------------------------------------------------------------

u32 nPlayerX;
u32 nPlayerY;
u32 nPlayerAngle;

int fKeyUp; //bool fKeyUp=false;
int fKeyDown; //bool fKeyDown=false;
int fKeyLeft; //bool fKeyLeft=false;
int fKeyRight; //bool fKeyRight=false;

u16* FrontBuffer = (u16*)0x6000000;
u16* BackBuffer = (u16*)0x600A000;
u16* videoBuffer;
u16* paletteMem = (u16*)0x5000000;

//----------------------------------------------------------------
// prototipo de la funciones utilizadas.
//----------------------------------------------------------------
void drawBackground(void); // esta función básicamente permite limpiar la pantalla de la GBA.
void renderWalls(); // permite dibujar los muros.
void WaitForVsync(void); // función de espera al vsync.
void updateKeyVars(); // comprueba el registro de teclado y modifica las cuatro variables globales definidas antes.
void Flip(void); // conmuta al buffer que va ser visto por la pantalla de la GBA.
void move(int moveup); // nos permite mover al personaje. También gestiona el tema de las colisiones con los muros.
s32 absint(s32 d); // devuelve el valor absoluto de un valor entero.
s32 distAngle(s32 s1, s32 s2); // devuelve la distancia entre dos angulos.

//----------------------------------------------------------------
// PROGRAMA PRINCIPAL . MAIN(*).
//----------------------------------------------------------------

int main(int argc, char* argv[]){
char x;
char changed = 0;

SetMode(MODE_4 | BG2_ENABLE ); //en este ejemplo vamos a utilizar el modo gráfico 4 de la GBA y además vamos a activar
//el background MODE 2.

for(x = 0; x < 16; x++) // plaeta
paletteMem[x] = gPalette[x];

nPlayerX = 96; // coordenadas iniciales X
nPlayerY = 128; // coordenadas iniciales X
nPlayerAngle = 0; // hacia la derecha.

Flip();// conmuta al buffer que va ser visto por la pantalla de la GBA.
drawBackground();
renderWalls(); // dibujamos los muros.
Flip();// conmuta al buffer que va ser visto por la pantalla de la GBA.

while(true){// bucle infinito.
// en el bucle infinito procesamos los movimientos del personaje.
if (fKeyLeft){
nPlayerAngle += 10;
if (nPlayerAngle >= 360) nPlayerAngle = 0;
changed = 1;
}

else if (fKeyRight){
if (nPlayerAngle < 10) nPlayerAngle = 350;
else nPlayerAngle -= 10;
changed = 1;
}

if (fKeyUp)
{
move(1); // comprueba si ha habido colisiones del personaje con
//alguno de los muros después de haberse producido un movimiento.
changed = 1;
}
else if (fKeyDown)
{
move(0); // comprueba si ha habido colisiones del personaje con
//alguno de los muros después de haberse producido un movimiento.
changed = 1;
}


if (changed) // only redraw if they push a key and change the screen
{
changed = 0;
drawBackground(); // esta función básicamente permite limpiar la pantalla de la GBA.
renderWalls(); // permite dibujar los muros.
WaitForVsync(); // función de espera al vsync.
Flip(); // conmuta al buffer que va ser visto por la pantalla de la GBA.
}
updateKeyVars();
}

return 0;
}//fin del metodo.

//------------------------------------------------------------------------------------------
// nos permite mover al personaje. También gestiona el tema de las colisiones con los muros.
//------------------------------------------------------------------------------------------
void move(int moveup) {
double deltaX;
double deltaY;

if (moveup){
deltaX = (tableCOS[nPlayerAngle] * 15);
deltaY = -1*(tableSIN[nPlayerAngle] * 15);
}
else{
deltaX = -1*(tableCOS[nPlayerAngle] * 15);
deltaY = (tableSIN[nPlayerAngle] * 15);
}

int newX = (int)(nPlayerX + deltaX + (8 * abs(deltaX) / deltaX));
int newY = (int)(nPlayerY + deltaY + (8 * abs(deltaY) / deltaY));

if (fMap[(newX/64) + MAPWIDTH * (newY/64)] == O) {
nPlayerX += (int) deltaX;
nPlayerY += (int) deltaY;
} else if (fMap[(newX/64) + MAPWIDTH * (nPlayerY/64)] == O) {
nPlayerX += (int) deltaX;
} else if (fMap[(nPlayerX/64) + MAPWIDTH * (newY/64)] == O) {
nPlayerY += (int) deltaY;
}
}//fin de la función.

//----------------------------
// función de espera al vsync.
//----------------------------
void WaitForVsync(void){
while(REG_VCOUNT<160);
}//fin de la función.

//------------------------------------------------------------------------------------------------------------------
//esta función nos permite ir chequendo las variables que hemos definido para el control de las teclas de dirección.
//la correspondencia con las teclas del PAD está registrada en el fichero de cabecera keypad.h.
//------------------------------------------------------------------------------------------------------------------
void updateKeyVars(){
fKeyUp = fKeyDown = fKeyLeft = fKeyRight = 0;

if(!((*KEYS) & KEY_UP)){
fKeyUp = 1;
}
if(!((*KEYS) & KEY_DOWN)){
fKeyDown = 1;
}
if(!((*KEYS) & KEY_LEFT)){
fKeyLeft=1;
}
if(!((*KEYS) & KEY_RIGHT)){
fKeyRight=1;
}
if(!((*KEYS) & KEY_A)){
//esta tecla no tiene función asignada.... aun.
}
if(!((*KEYS) & KEY_B)){
//esta tecla no tiene función asignada.... aun.
}
if(!((*KEYS) & KEY_R)){
//esta tecla no tiene función asignada.... aun.
}
if(!((*KEYS) & KEY_L)){
//esta tecla no tiene función asignada.... aun.
}
}//fin de la función.

//----------------------------------------------------------------
// esta función básicamente permite limpiar la pantalla de la GBA.
//----------------------------------------------------------------
void drawBackground(void){
u16* destBuffer =videoBuffer;
u8 loop;
for (loop = 0; loop < 8; loop++)
{
u16 val = (loop << 8) + loop;
u16* finalAdr=destBuffer+SHORT_LINE;
while(destBuffer<finalAdr)
*destBuffer++=val;
}
for (loop = 8; loop < 14; loop++)
{
u16 val = (loop<<8) + loop;
u16* finalAdr=destBuffer+LONG_LINE;
while(destBuffer<finalAdr)
*destBuffer++=val;
}
}//fin de la función.


//-----------------------------------------------
// devuelve el valor absoluto de un valor entero.
//-----------------------------------------------
s32 absint(s32 d){
if (d < 0) d *= -1;
return d;
}//fin de la función.

//-----------------------------------------
// devuelve la distancia entre dos angulos.
//-----------------------------------------
s32 distAngle(s32 s1, s32 s2){
s32 temp;
if (s2 >= s1)
temp = s2 - s1;
else
temp = s1 - s2;
if (temp > 30) temp -= 360;
return absint(temp);
}//fin de la función.

//-------------------------------------------------------------------------------------------------------
// Aqui dejo la definición del sistema de coordenadas que emplea el autor para definir la tabla en trig.h
//-------------------------------------------------------------------------------------------------------
// 90 deg, y--
// |
// |
// QUAD2 | QUAD1
// |
// |
// |
// x--, 180 deg --------------------------- 0 deg, x++
// |
// |
// QUAD3 | QUAD4
// |
// |
// |
// 270 deg, y++
//----------------------------------------------------

//------------------------------------------------------------------------------
// Esta función nos permite pintar los muros que forman parte del mapa definido.
//------------------------------------------------------------------------------
void renderWalls(){
u32 loop;
s16 curAngle;
s32 gridX; // coordenada X en el mapa
s32 gridY; // coordenada Y en el MAPA
u16* destBuffer = videoBuffer; // apunta al buffer donde se pintan los muros.
u8 x,y;

double horzLength; // distancia al muro en horizontal (desde el pto de perpectiva del tio que anda.)
double vertLength; // distancia al muro en vertical (desde el pto de perpectiva del tio que anda.)
double* minLength;
u32 lineLength;

char darkgray = 0; // vertical --> darkgray, horzontal --> lightgray

double fdistNextX;
double fdistNextY;
int ndistNextX;
int ndistNextY;

int horzY;
double horzX;
int vertX;
double vertY;

curAngle = nPlayerAngle + 30; // angulo de inicio.
if (curAngle >= 360) curAngle -= 360;

// 4 = SCREENWIDTH / 64 (TILEHEIGHT)
for (loop = 0; loop < SCREENWIDTH; loop+=4) {
// calcula la distancia horizontal.
if (curAngle == 0 || curAngle == 180){
// no hay un muro en la dirección horizontal
horzLength = 9999999.00;
}
else{
if (curAngle < 180){
horzY = (nPlayerY/64) * 64;
ndistNextY = -64;
double amountChange = ((s32) (horzY - nPlayerY) ) * tableINVTAN[curAngle];
if (curAngle < 90 || curAngle > 270){
if (amountChange < 0) amountChange *= -1;
}
else {
if (amountChange > 0) amountChange *= -1;
}
horzX = nPlayerX + amountChange;
horzY--;
}
else {
horzY = (nPlayerY/64) * 64 + 64;
ndistNextY = 64;
double amountChange = ((s32)(horzY - nPlayerY)) * tableINVTAN[curAngle];
if (curAngle < 90 || curAngle > 270){
if (amountChange < 0) amountChange *= -1; // should be pos
}
else {
if (amountChange > 0) amountChange *= -1;
}
horzX = nPlayerX + amountChange;
}
fdistNextX = (64.00 * tableINVTAN[curAngle]);
if ( (curAngle < 90) || (curAngle>270) ){
if (fdistNextX < 0) fdistNextX *= -1; // distancia positiva al siguiente bloque
}
else{
if (fdistNextX > 0) fdistNextX *= -1; // distancia negativa al siguiente bloque
}

while (true){
gridX = (s32)(horzX / 64);
gridY = (s32)(horzY / 64);
if (gridX >= MAPWIDTH || gridY >= MAPHEIGHT || gridX < 0 || gridY < 0)
{
horzLength = 9999999.00;
break;
}
else if (fMap[gridX+gridY*MAPHEIGHT])
{
horzLength = (horzX - nPlayerX) * tableINVCOS[curAngle];
break;
}
horzX += fdistNextX;
horzY += ndistNextY;
}
}
// calcula la distancia vertical.
if (curAngle == 90 || curAngle == 270){
vertLength = 9999999.00;
}
else{
if (curAngle < 90 || curAngle > 270){
vertX = (nPlayerX/64) * 64 + 64;
ndistNextX = 64;
double amountChange = tableTAN[curAngle]*((s32)(vertX-nPlayerX));
if (curAngle < 180){
if (amountChange > 0) amountChange *= -1;
}
else
{
if (amountChange < 0) amountChange *= -1;
}
vertY = nPlayerY + amountChange;
}
else{
vertX = (nPlayerX/64) * 64;
ndistNextX = -64;
double amountChange = tableTAN[curAngle]*((s32)(vertX-nPlayerX));
if (curAngle < 180){
if (amountChange > 0) amountChange *= -1;
}
else{
if (amountChange < 0) amountChange *= -1;
}
vertY = nPlayerY + amountChange;
vertX--;
}
fdistNextY = 64.00 * tableTAN[curAngle];
if (curAngle < 180) {
if (fdistNextY > 0) fdistNextY *= -1;
}
else{
if (fdistNextY < 0) fdistNextY *= -1;
}

while (true){
gridX = (s32)(vertX / 64);
gridY = (s32)(vertY / 64);
if (gridX >= MAPWIDTH || gridY >= MAPHEIGHT || gridX < 0 || gridY < 0)
{
vertLength = 9999999.00;
break;
}
else if (fMap[gridX+gridY*MAPHEIGHT])
{
vertLength = (vertY - nPlayerY) * tableINVSIN[curAngle];
break;
}
vertX += ndistNextX;
vertY += fdistNextY;
}
}

if (vertLength < 0) vertLength *= -1;
if (horzLength < 0) horzLength *= -1;

if (vertLength < horzLength){
minLength = &vertLength;
darkgray = 1;
}
else{
darkgray = 0;
minLength = &horzLength;
}

//arreglar la distorsión.
(*minLength) = (*minLength) * tableCOS[distAngle(curAngle, nPlayerAngle)];

lineLength = absint((s32)((64.00 / *minLength) * PLAY_LENGTH) );

int end = (80 - lineLength/2);
int start;
if (end < 0){
end = 160;
start = 0;
}
else{
start = end;
end += lineLength;
}

u32 where = loop/2 + start*120;
if (darkgray){
for(y = start; y<end; y++)
{
destBuffer[where] = 0x0f0f;
destBuffer[where+1] = 0x0f0f;
where += 120;
}
}
else{
for(y = start; y<end; y++){
destBuffer[where] = 0x0e0e;
destBuffer[where+1] = 0x0e0e;
where += 120;
}
}

curAngle -= 1;
if (curAngle < 0) curAngle += 360;

}
}//fin de la función.

//--------------------------------------------------------------
// conmuta al buffer que va ser visto por la pantalla de la GBA.
//--------------------------------------------------------------
void Flip(void){
if(REG_DISPCNT & BACKBUFFER){
REG_DISPCNT &= ~BACKBUFFER; //el buffer activo es el frontal, por tanto limpiamos el buffer trasero.
videoBuffer = BackBuffer; //apuntamos el buffer de dibujo al buffer trasero.
}
else{
REG_DISPCNT |= BACKBUFFER; //el buffer activo es el trasero, por tanto limpiamos el buffer frontal.
videoBuffer = FrontBuffer; //apuntamos el buffer de dibujo al buffer frontal..
}
}//fin de la función.



Finalmente os pongo un par de capturillas y la ROM final (ya fixeada y lista para probar en emuladores y GBA FlashCart) junto con el código fuente de todo el proyecto.:awesome:

Una cosilla que quería preguntar a modo general: Resulta que estaba hechandole un ojo ayer por la tarde a los tutos del GBADEV y viene uno, en el cual se explica como realizar un programa en C con el devkitPRO de tal forma que al compilarlo nos genera una ROM que al ejecutarla en la GBA, nos genera un fichero .bin con la imagen de la BIOS de la GBA copiada en ella. La cosa es que me gustaria comentarlo por aqui, subir el código y demás , pero creo que va encontra de las normas del foro, no?. En fin a disfrutar. SALUDOS.:awesome:

GameMaster
20/06/2010, 17:12
:babea::babea::babea::babea::babea::babea::babea:
:babea::babea::babea::babea::babea::babea::babea:
:babea::babea::babea::babea::babea::babea::babea:

jduranmaster
20/06/2010, 17:17
vaya cuanto entusiasmo.:awesome:

tSuKiYoMi
20/06/2010, 20:08
joer que WAPO.:awesome:. No me esperaba menos, que grande eres jduran.

[<_-_Ukyo_-_>]
20/06/2010, 20:15
La verdad es que este juego con perspectiva tipo FPS al mas puro estilo DooM no ha quedado nada mal, lo acabo de bajar y lo voy a probar en el VisualBoy Advance. Sino lo he entendido mal el muñeco no dispará, no solo te puedes desplazar por el mapa, que ya es mucho, correcto? En el código fuente comentas que podemos cambiar la disposición del mapa, es tan simple como coger y cambiar una O por una W y con eo ya podemos tirar paredes? En serio te ha quedado muy bien.:p

jduranmaster
20/06/2010, 22:22
gracias por los apoyos. Efectivamente Ukyo, te basta solo con cambiar O poe W para construir un muro en le definción del fichero .c que he pasado y recompilar todo de nuevo para que los cambios en el mapa sean efectivos.SALUDOS.:awesome:

xzakox
20/06/2010, 22:32
Muy guapo :-)

jduranmaster
20/06/2010, 22:35
gracias a todos por los apoyos. Y hago una petición, a ver si alguien puede probarlo en el emu de GBA de la Wiz, que no tengo la Wiz a mano ahora mismo y me gustaria saber si funciona en ella. SALUDOS.:awesome:

jduranmaster
21/06/2010, 11:37
Aqui os paso un nuevo ejemplo para GBA desarrollado empleando el devkitPRO. Se trata de un ejemplo que usa el modo gráfico 0 de la GBA para mostrara un mensaje de texto en scroll horizontal y que utiliza una fuente customizada y creada por el usuario. Los includes significativos que uso en el ejemplo son los isguientes:




//---------------------------------------
// INCLUDES
//---------------------------------------
#include <gba_base.h>
#include <gba_video.h>
#include <gba_systemcalls.h>
#include <gba_interrupt.h>

#include "r6502_portfont_bin.h"



los 4 includes del principio son propios del devkitPRO, pero se podría probar si el ejemplo es recompilable usando el devkitADV. El devkitPRO usa la libgba que es una libreria especial que de la que se sirven todos los programas realizados en el devkitPRO, asi que me imagino que incluyendo dicha libreria en un proyecto con devkitADV debería poder recompilarse con ese kit de desarrollo sin problemas, sin embargo esto último no lo he llegado a probar nunca. La fuente del texto está definida en el fichero de cabecra que tmb incluyo "r6502_portfont_bin.h".Aqui os dejo el código fente del programa principal:




//---------------------------------------
//@author: jduranmaster
//@version: 1.0
//@title: scroll.c
//---------------------------------------


//---------------------------------------
// INCLUDES
//---------------------------------------
#include <gba_base.h>
#include <gba_video.h>
#include <gba_systemcalls.h>
#include <gba_interrupt.h>

#include "r6502_portfont_bin.h"


//----------------------------------------
// DEFINES
//----------------------------------------
// --------------------------------------------------------------------

#define MAPADDRESS MAP_BASE_ADR(31) // mapa base de direcciones.
#define DELAY 2 // retardo.
#define TILEWIDTH 8 // longitud del scroll.
#define ROW 10 // fila.

// --------------------------------------------------------------------

const u16 paleta[] = {
RGB8(0x40,0x80,0xc0),
RGB8(0xFF,0xFF,0xFF),
RGB8(0xF5,0xFF,0xFF),
RGB8(0xDF,0xFF,0xF2),
RGB8(0xCA,0xFF,0xE2),
RGB8(0xB7,0xFD,0xD8),
RGB8(0x2C,0x4F,0x8B)
};

// --------------------------------------------------------------------

const u8 mensaje[] = {
" " \
"^_^ Este es un ejemplo de ROM para GBA realizado con el devkitPRO " \
"para mostrar un ejemplo de scroll horizontal en pantalla. " \
"JdUrAnMaStEr. 2010. ^_^ "
};

// --------------------------------------------------------------------


void actualizaTexto(u32 idx){
u32 i;
u16 *temp;

temp = (u16 *)MAPADDRESS + (ROW * 32);

// escribimos una linea de texto completa en el mapa.
for(i=0; i<32; i++){
if(mensaje[idx] == 0) idx = 0;

*temp++ = mensaje[idx++] - 32;
}
}//fin de la función.


int main() {
// cargamos los manejadores de interrupciones.
irqInit();
//permitimos que se pueda ejecutar VBLANK.
irqEnable(IRQ_VBLANK);

// permitir interrupciones.
REG_IME = 1;

u32 i, scrollx, scrolldelay, textindex;
u16 *temp;


// cargamos la paleta.
temp = BG_COLORS;
for(i=0; i<7; i++) {
*temp++ = paleta[i];
}

// cargamos el tipo de fuente de texto que usaremos (definida en el .h) (48 caracteres, tiles de 4 bits)

CpuFastSet(r6502_portfont_bin, (u16*)VRAM,(r6502_portfont_bin_size/4) | COPY32);

// limpiamos el mapa completo.

*((u32 *)MAP_BASE_ADR(31)) =0;
CpuFastSet( MAP_BASE_ADR(31), MAP_BASE_ADR(31), FILL | COPY32 | (0x800/4));

// fijamos las posiciones del scroll vertical y horizontal.
BG_OFFSET[0].x = 0; BG_OFFSET[0].y = 0;

// inicializamos nuestras variables.
scrollx = 0;
textindex = 0;
scrolldelay = 0;

*((u16 *)MAPADDRESS + 1) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 5) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 10) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 15) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 20) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 25) = 0x20; // 0x20 == '@'

*((u16 *)MAPADDRESS + 30) = 0x20; // 0x20 == '@'

// comenzamos a escribir el texto.
actualizaTexto(0);

BGCTRL[0] = SCREEN_BASE(31);

// activamos el modo gráfico 0 de la GBA y background activo.
SetMode( MODE_0 | BG0_ON );

while(1) {
VBlankIntrWait();

//comprobamos is hemos alcanzado el retardo fijado.
if(scrolldelay == DELAY) {
scrolldelay = 0;

if(scrollx == (TILEWIDTH-1)) {
scrollx = 0;

//comprobamos si hemos alcanzado el final del texto.
if(mensaje[textindex] == 0) textindex = 0;
else textindex++;

//actualizamos con la posición actual.
actualizaTexto(textindex);
}
else scrollx++;
}
else scrolldelay++;
BG_OFFSET[0].x = scrollx;
}

}//fin del main.



Finalmenet os incluyo unas capturas y la ROM por si quereis probar. SALUDOS.:awesome:

jduranmaster
21/06/2010, 12:37
Aqui os dejo un nueva ROM nueva en la que he incluido los sprites de un "METROID". El proyecto esta realizado empleando el devkitPRO para GBA, y hace uso de INCLUDES especificos de este kit de desarrollo. Son los siguientes:




#include "toolbox.h"
#include "metr.h"



ToolBox.h a su vez incluye otros .h que forman parte de la distribución del devkitPRO, minetras que metr.h es el fichero resultado de hbaer usado el PCX2GBA para obtener los bytes de las imagen del METROID que sale en la ROM. Con los botones del PAD podemos desplazar al METROID por la pantalla, darle la vuelta en horizontal y en vertical, cambiar su paleta de colores, etc.... Aqui os dejo el código del programa principal.




//------------------------------------------
//author: jduranmaster
//version: 1.0
//title: metroid
//------------------------------------------

#include <string.h>
#include "toolbox.h"
#include "metr.h"

OBJ_ATTR obj_buffer[128];
OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer;

// tenemo varias opciones para modificar el sprite.
// D-pad: permite mover
// SELECT: cambia la paleta.
// START: mapeo de tipo toggle.
// A: flip horizontal.
// B: flip vertical.
// L & R: desplazamiento de los tiles.

void obj_test(){
int x= 96, y= 32;
u32 tid= 0, pb= 0; // identificador del tile.

OBJ_ATTR *metr= &obj_buffer[0];// creamos una estructura para poder referenciar al metroid.
obj_set_attr(metr, ATTR0_SQUARE,ATTR1_SIZE_64,ATTR2_PALBANK(pb) | tid);//fijamos los siguientes parámetros:
// palbank 0,64x64p, cuadrado, 64x64
//fijamos la posición del sprite. ^_^
obj_set_pos(metr, x, y);

while(1){
vid_vsync();
key_poll();

//desplazamiento horizontal (eje X).
x += 2*key_tri_horz();

//desplazamiento vertical (eje Y).
y += 2*key_tri_vert();

// con L & R modificamos el valor del identicador del tile.
tid += bit_tribool(key_hit(-1), KI_R, KI_L);

// flip
if(key_hit(KEY_A)) // horizontal
metr->attr1 ^= ATTR1_HFLIP;
if(key_hit(KEY_B)) // vertical
metr->attr1 ^= ATTR1_VFLIP;

// con select modificamos la paleta del metroid...... ^_^
pb= key_is_down(KEY_SELECT) ? 1 : 0;

// toggle
if(key_hit(KEY_START))
REG_DISPCNT ^= DCNT_OBJ_1D;

metr->attr2= ATTR2_BUILD(tid, pb, 0);
obj_set_pos(metr, x, y);//fijar la posición del metroid
//en función de las teclas del DPAD que hayamos pulsado.

oam_copy(oam_mem, obj_buffer, 1);
}
}//fin de la función.

int main(){


memcpy(&tile_mem[4][0], metrTiles, metrTilesLen);
memcpy(pal_obj_mem, metrPal, metrPalLen);

//inicializamos.
oam_init(obj_buffer, 128);
REG_DISPCNT= DCNT_OBJ | DCNT_OBJ_1D;

obj_test();//llamamos a la función que controla el comportamiento
//del metroid, y chequea las teclas.

while(1);

return 0;
}//fin del main.



La ROM generada ya tiene la cabecera "fixeada" de tal forma que se puede probar perfectamente en una GBA real mediante flashcart. Os dejo tmb una capturas de pantalla para que veais como ha quedado y la ROM para que la probeis. SALUDOS.:awesome:

saucjedi
21/06/2010, 12:59
Aqui os dejo un nueva ROM nueva en la que he incluido los sprites de un "METROID". El proyecto esta realizado empleando el devkitPRO para GBA, y hace uso de INCLUDES especificos de este kit de desarrollo. Son los siguientes:




#include "toolbox.h"
#include "metr.h"



ToolBox.h a su vez incluye otros .h que forman parte de la distribución del devkitPRO, minetras que metr.h es el fichero resultado de hbaer usado el PCX2GBA para obtener los bytes de las imagen del METROID que sale en la ROM. Con los botones del PAD podemos desplazar al METROID por la pantalla, darle la vuelta en horizontal y en vertical, cambiar su paleta de colores, etc.... Aqui os dejo el código del programa principal.




//------------------------------------------
//author: jduranmaster
//version: 1.0
//title: metroid
//------------------------------------------

#include <string.h>
#include "toolbox.h"
#include "metr.h"

OBJ_ATTR obj_buffer[128];
OBJ_AFFINE *obj_aff_buffer= (OBJ_AFFINE*)obj_buffer;

// tenemo varias opciones para modificar el sprite.
// D-pad: permite mover
// SELECT: cambia la paleta.
// START: mapeo de tipo toggle.
// A: flip horizontal.
// B: flip vertical.
// L & R: desplazamiento de los tiles.

void obj_test(){
int x= 96, y= 32;
u32 tid= 0, pb= 0; // identificador del tile.

OBJ_ATTR *metr= &obj_buffer[0];// creamos una estructura para poder referenciar al metroid.
obj_set_attr(metr, ATTR0_SQUARE,ATTR1_SIZE_64,ATTR2_PALBANK(pb) | tid);//fijamos los siguientes parámetros:
// palbank 0,64x64p, cuadrado, 64x64
//fijamos la posición del sprite. ^_^
obj_set_pos(metr, x, y);

while(1){
vid_vsync();
key_poll();

//desplazamiento horizontal (eje X).
x += 2*key_tri_horz();

//desplazamiento vertical (eje Y).
y += 2*key_tri_vert();

// con L & R modificamos el valor del identicador del tile.
tid += bit_tribool(key_hit(-1), KI_R, KI_L);

// flip
if(key_hit(KEY_A)) // horizontal
metr->attr1 ^= ATTR1_HFLIP;
if(key_hit(KEY_B)) // vertical
metr->attr1 ^= ATTR1_VFLIP;

// con select modificamos la paleta del metroid...... ^_^
pb= key_is_down(KEY_SELECT) ? 1 : 0;

// toggle
if(key_hit(KEY_START))
REG_DISPCNT ^= DCNT_OBJ_1D;

metr->attr2= ATTR2_BUILD(tid, pb, 0);
obj_set_pos(metr, x, y);//fijar la posición del metroid
//en función de las teclas del DPAD que hayamos pulsado.

oam_copy(oam_mem, obj_buffer, 1);
}
}//fin de la función.

int main(){


memcpy(&tile_mem[4][0], metrTiles, metrTilesLen);
memcpy(pal_obj_mem, metrPal, metrPalLen);

//inicializamos.
oam_init(obj_buffer, 128);
REG_DISPCNT= DCNT_OBJ | DCNT_OBJ_1D;

obj_test();//llamamos a la función que controla el comportamiento
//del metroid, y chequea las teclas.

while(1);

return 0;
}//fin del main.



La ROM generada ya tiene la cabecera "fixeada" de tal forma que se puede probar perfectamente en una GBA real mediante flashcart. Os dejo tmb una capturas de pantalla para que veais como ha quedado y la ROM para que la probeis. SALUDOS.:awesome:

¿Esto no es un ejemplo de TONC? Concretamente creo que uno de los de este capítulo: http://www.coranac.com/tonc/text/regobj.htm

Si es así, que me da la impresión de que sí, este comentario:



// START: mapeo de tipo toggle


está mal traducido, realmente es



// START: cambia el tipo de mapeo (toggle mapping type)


¿Qué significa esto? Cuando un objeto está compuesto por varios sprites hardware, como nuestro metroid, se establece un mapeo. El mapeo 2D y el 1D. Básicamente es la forma en que se guarda en memoria el sprite: puede guardarse conservando la forma original o con los sprites uno tras otro en posiciones de memoria contiguas. En TONC está muy bien explicado.

Si no recuerdo mal, ToolBox NO forma parte de DevkitPRO sino de TONC, del tutorial. Al menos así era cuando le daba a esto de forma contínua.

(Respecto los SDK... tengo problemas con Megaupload y similares en mi conexión, no sé qué pasa. ¿Hace un torrent?)

jduranmaster
21/06/2010, 13:02
si es un ejemplo de TONC de los que estoy siguiendo , toolbox, es es de las que llama a otros .h incluidos en el proecto TONC pero tmb hace uso de .h del devkitPRO.

Pues no tengo torrent instalado ene sta máquina pero si lo puedes subir a otro tipo de sistema descargas mejor. pero vamos como veas.

saucjedi
21/06/2010, 13:07
si es un ejemplo de TONC de los que estoy siguiendo , toolbox, es es de las que llama a otros .h incluidos en el proecto TONC pero tmb hace uso de .h del devkitPRO.

Pues no tengo torrent instalado ene sta máquina pero si lo puedes subir a otro tipo de sistema descargas mejor. pero vamos como veas.

Con el cliente normal de bittorrent no debería haber problemas y si hay más gente interesada, más rápido bajará...

Los .h del DevkitPro son simples defines... el meollo está en ToolBox. De hecho, ToolBox lo va construyendo poco a poco a medida que avanza el tutorial (aunque más que tutorial yo lo llamaría libro... TONC es un pedazo de curro).

jduranmaster
21/06/2010, 13:12
Con el cliente normal de bittorrent no debería haber problemas y si hay más gente interesada, más rápido bajará...

Los .h del DevkitPro son simples defines... el meollo está en ToolBox. De hecho, ToolBox lo va construyendo poco a poco a medida que avanza el tutorial (aunque más que tutorial yo lo llamaría libro... TONC es un pedazo de curro).

ok usare el bittorrent pues. Más adelante va usando el ToolBox para hacer cosas cada vez más complicadillas, hay un ejemplo por ahi donde se cogen y hacen una especiae de animación con dos cadenas que esta supercurrado.

xzakox
21/06/2010, 14:26
Tengo casi listo un nuevo ejemplo sobre como usar el timer de la gameboy y controlarlo mediante interrupciones, muy interesantes para obtener timings correctos y no preocuparnos de controlarlo a mano.
Además usa la interrupción de VBlank para dibujar.
Esta noche lo subo :-)

jduranmaster
21/06/2010, 14:30
muy wapo. espero verlo pronto.:awesome:

xzakox
21/06/2010, 15:01
Juas, al final han cambiao los planes y tenia una hora más libre, asi que aqui lo teneis:

http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador#hola_timer

:-)

jduranmaster
21/06/2010, 15:40
lo acabo de probar, muy bueno como siempre tio. puedes explicar más en detalle estas dos rutinas?:




DibujaCronometro:
; decenas de horas
ld a, [_HORAS]
and $F0
swap a
ld [_POS_CRONOM], a
; horas
ld a, [_HORAS]
and $0F
ld [_POS_CRONOM+1], a
; :
ld a, 10
ld [_POS_CRONOM+2], a
; decenas de minutos
ld a, [_MINUTOS]
and $F0
swap a
ld [_POS_CRONOM+3], a
; minutos
ld a, [_MINUTOS]
and $0F
ld [_POS_CRONOM+4], a
; :
ld a, 10
ld [_POS_CRONOM+5], a
; decenas de segundos
ld a, [_SEGUNDOS]
and $F0
swap a
ld [_POS_CRONOM+6], a
; segundos
ld a, [_SEGUNDOS]
and $0F
ld [_POS_CRONOM+7], a

ret

; Controla el tiempo
ControlTimer:
ld a, [_CONTROL_TIEMPO]
cp 20 ; cada 20 interrupciones, pasa 1 seg
jr z, .incrementa
inc a ; si no, incrementamos y volvemos
ld [_CONTROL_TIEMPO], a
ret
.incrementa
; reseteamos el contador
ld a, 0
ld [_CONTROL_TIEMPO], a
; incrementamos los segundos
ld a, [_SEGUNDOS]
inc a
daa
cp 96 ; han pasado 60 segundos? (96 porque usamos BCD)
jr z, .minutos ; si, a controlar los minutos

ld [_SEGUNDOS], a ; no, guardamos y volvemos
ret
.minutos
ld a, 0
ld [_SEGUNDOS], a ; incrementar el minuto, segundos a 0

ld a, [_MINUTOS]
inc a
daa
cp 96 ; han pasado 60 minutos?
jr z, .horas ; si, a controlar las horas

ld [_MINUTOS], a ; no, guardamos y volvemos
ret
.horas
ld a, 0
ld [_MINUTOS], a ; incrementar el minuto, segundos a 0

ld a, [_HORAS]
inc a
daa
cp 36 ; han pasado 24 horas? (36 equivale a 24 en BCD)
jr z, .reset ; si, a volver a empezar

ld [_HORAS], a ; no, guardamos y volvemos
ret
.reset
call Resetea

ret

xzakox
21/06/2010, 15:45
Ahora si me tengo que pirar, de noche las explico.

^OMAP-Cranck^
21/06/2010, 20:21
Vaya este hilo es muy interesante. Aun conservo mi vieja GameBoy Advance con cartucho flashcart, y una GameBoy color Transparente. Si las roms que se han hecho para GBA son compatibles con el FlashCart de GBA las probare.:hype:

xzakox
21/06/2010, 22:20
Bien vamos con las explicaciones. Primero voy a explicar ControlTimer, porque nos ayudará a explicar mejor la otra.



; Controla el tiempo
ControlTimer:
ld a, [_CONTROL_TIEMPO]
cp 20 ; cada 20 interrupciones, pasa 1 seg
jr z, .incrementa
inc a ; si no, incrementamos y volvemos
ld [_CONTROL_TIEMPO], a
ret
Como explico en el tutorial, tenemos que con el timer a 4096Hz y con el timer con valor inicial 51, se llama a la interrupción del timer cada aprox 0.05 segundos, asi que para contar de 1 en 1 segundos para el cronómetro, lo que hacemos aqui es contar las veces que se llama a esta subrutina, si se la ha llamado 20 veces, han pasado 0.05 * 20 = 1 segundo, asi que vamos a modificar el tiempo, si no, incrementamos el contador y volvemos.




.incrementa
; reseteamos el contador
ld a, 0
ld [_CONTROL_TIEMPO], a
; incrementamos los segundos
ld a, [_SEGUNDOS]
inc a
daa
cp 96 ; han pasado 60 segundos? (96 porque usamos BCD)
jr z, .minutos ; si, a controlar los minutos

ld [_SEGUNDOS], a ; no, guardamos y volvemos
ret

Bien, ahora vamos a incrementar el tiempo ya que ha pasado 1 segundo, primero reseteamos el contador de veces que se llama a la función, porque como han pasado 20, tenemos que volver a contar desde cero.

Luego vamos a aumentar los segundos. Cargamos en A los segundos, y le sumamos uno, entonces tenemos que ver si el resultado es mayor que 60, porque si es asi, tenemos que poner los segundos a cero, y sumar un minuto. Pero veis que uso daa. daa es una instrucción, que lo que hace es convertir el contenido de A a BCD (Binary Coded Decimal), si conoceis BCD, los numeros binarios en lugar de guardarse tal cual, se guardan en un byte de manera que cada 4 bits representan un numero del 0 al 9, y no del 0 al 15 como podria ser en base 2 normal. Esto es muy útil porque aunque con un byte sólo podemos guardar de 0 a 99, en cada medio byte tengo unidades y decenas respectivamente del número de segundos/minutos/horas, y esto nos será muy útil para luego dibujarlos. Asi que convierto el contenido de A en BCD y lo comparo con 60 (que en BCD es 0110 (6) y 0000 (0), 01100000 y eso es 96 representado en binario normal, que es lo que entiende el procesador al comparar, que el contenido en binario sea igual, por eso comparo con 96), si tenemos mas de 60 segundos, salto a aumentar los minutos, si no, guardo el resultado en los segundos, y vuelvo.




.minutos
ld a, 0
ld [_SEGUNDOS], a ; incrementar el minuto, segundos a 0

ld a, [_MINUTOS]
inc a
daa
cp 96 ; han pasado 60 minutos?
jr z, .horas ; si, a controlar las horas

ld [_MINUTOS], a ; no, guardamos y volvemos
ret
.horas
ld a, 0
ld [_MINUTOS], a ; incrementar el minuto, segundos a 0

ld a, [_HORAS]
inc a
daa
cp 36 ; han pasado 24 horas? (36 equivale a 24 en BCD)
jr z, .reset ; si, a volver a empezar

ld [_HORAS], a ; no, guardamos y volvemos
ret
.reset
call Resetea

ret

Y aqui es casi lo mismo para los minutos y las horas. Para los minutos, lo primero que hago es poner los segundos a cero (59-->0) y luego incremento los minutos y hago lo mismo que con los segundos, comprobar si han pasado 60 y en caso afrimativo ir a aumentar las horas, y si no volver. Y con las horas igual, sólo que si llegan a pasar 24 horas, reseteo, pongo todo a cero, y ale, a volver a empezar.


Y ahora explico la rutina que dibuja el cronómetro, que es muy sencilla.
Al inicio he definido una constante llamada _POS_CRONOM, tal que: _SCRN0+32*4+6. ¿Que significa eso? _SCRN0 era la dirección en memoria del mapa de fondo, donde se guarda que tile pintar en cada posición de los 32*32 tiles de fondo. Si a eso le sumo 32*4, obtengo, 32 bytes más adelante * 4 = La cuarta linea, y si le sumo 6, pues la cuarta linea de la pantalla, más 6 posiciones, el punto donde empezaré a dibujar el cronómetro.
Y a partir de aqui es muy sencillo. Tengo que empezar a dibujar por las decenas de horas, luego las horas, luego los dos puntos, luego decenas de minutos... etc. Pues viendo el principio de la rutina:


; decenas de horas
ld a, [_HORAS]
and $F0
swap a
ld [_POS_CRONOM], a
; horas
ld a, [_HORAS]
and $0F
ld [_POS_CRONOM+1], a
; :
ld a, 10
ld [_POS_CRONOM+2], a
Cargo en el registro A, el contenido de la variable horas, como está guardada en BCD, sé que en el medio byte superior tengo las decenas de horas y en el inferior las unidades. Asi que para dibujar las decenas, hago un and de su contenido con $F0, que es %11110000, asi que esto borra el contenido de la media parte baja, dejando igual la media parte alta, y entonces haciendo swap, cambio la media parte alta por la media baja, con lo que ahora tengo en A, sólo el número de decenas de horas. Entonces simplemente cargo ese número en la posición _POS_CRONOM, que me meterá ese número en esa posición del mapa de pantalla. Sabemos que la gameboy, dibuja el fondo cogiendo los tiles de la lista de tiles segun el número que le digamos, entonces meterá en esa posición de fondo el tile número igual al número de decenas de horas. Como nuestros tiles del 0 al 9 son precisamente los dibujos de los números del 0 al 9, la gameboy dibujará en esa posición el número correspondiente a las decenas de horas.
Luego para las unidades de horas, hacemos algo similar, pero lo que hacemos es el and contrario, con $0F, porque sólo nos interesa quedarnos con la parte baja (las unidades) y entonces no necesitamos el swap y dibujamos directamente el tile correspondiente al número, pero ahora en_POS_CRONOM+1, porque queremos dibujarlo una posición más a la derecha.
Luego dibujamos los dos puntos (tile 10), y hacemos lo mismo para decenas de minuto, unidades de minuto, etc, simplemente añadiendo posiciones a la dirección inicial para dibujar el resto de números.

^OMAP-Cranck^
21/06/2010, 22:26
:awesome: Que pedazo de tutorial para GBA y GB, entre xzakox y jduranmaster habeis puesto un motón de ejemplos muy guapos. espero contribuir en algo a este hilo.

jduranmaster
21/06/2010, 22:48
gracias por la explicación xzakox, ahora me queda mucho más claro, sobre todo la parte donde se pintan los tiles del reloj. SALUDOS.:awesome:

Allen_S
22/06/2010, 02:23
Hola Jduranmaster, de verdad me has sorprendido con todo lo que has hecho... el otro dia te prometí probar en mi GBA todos tus trabajos, dejame decirte que TODOS FUNCIONAN PERFECTAMENTE, usando GBA Sp + EZ FLASH IV (fw 1.67).

Lo que si me gustó mucho es el Flashback Legends... que genialidad, aunque cuando pongo "español" salgan textos en francés... no se porque.

Recuerdo que alguna vez encontre un reproductor de mp3 para la GBA, lamentablemente la version 2.0 era de pago, la 1.0 si la llegué a usar, si gustas revisar te dejo en enlace:

http://gbatemp.net/t208044-translation-request-gb-walkman-alpha-and-options

Y la verdad siempre quise publicar un tutorial usando esa aplicación pero por limitaciones en el idioma no lo llegue a concretar (sobre todo la version 2.0).

Espero que mi comentario no este fuera de lugar... se que uds hablan de roms, texturas y demás.... pero es que yo quería saber si hubieran algunas otras opciones.... el visor de imágenes del EZ Flash me parece genial por ejemplo.

Y bueno, mucha suerte y éxitos en el proyecto Jduranmaster.... se que conseguirás cosas increíbles.... si hay algo en que te pueda ayudar, solo avísame.

jduranmaster
22/06/2010, 11:58
Hola Jduranmaster, de verdad me has sorprendido con todo lo que has hecho... el otro dia te prometí probar en mi GBA todos tus trabajos, dejame decirte que TODOS FUNCIONAN PERFECTAMENTE, usando GBA Sp + EZ FLASH IV (fw 1.67).

Lo que si me gustó mucho es el Flashback Legends... que genialidad, aunque cuando pongo "español" salgan textos en francés... no se porque.

Recuerdo que alguna vez encontre un reproductor de mp3 para la GBA, lamentablemente la version 2.0 era de pago, la 1.0 si la llegué a usar, si gustas revisar te dejo en enlace:

http://gbatemp.net/t208044-translation-request-gb-walkman-alpha-and-options

Y la verdad siempre quise publicar un tutorial usando esa aplicación pero por limitaciones en el idioma no lo llegue a concretar (sobre todo la version 2.0).

Espero que mi comentario no este fuera de lugar... se que uds hablan de roms, texturas y demás.... pero es que yo quería saber si hubieran algunas otras opciones.... el visor de imágenes del EZ Flash me parece genial por ejemplo.

Y bueno, mucha suerte y éxitos en el proyecto Jduranmaster.... se que conseguirás cosas increíbles.... si hay algo en que te pueda ayudar, solo avísame.


Tranqui, no te preocuopes. El FlashBack Legends, que conste que no es mio. Es de un grupo Francés de desarrolladores. Yo tmb lo he probado en le GBA con Flashcart y simepre me sale en idioma francés, supongo que o esta mal hecha la selección de idioma, o bien es que no está implementado y coge el de por defecto.

Lo del reproductor de MP3 para GBA lo mirare, y si quieres podemos comentarlo por aqui. SALUDOS.:awesome:

^OMAP-Cranck^
22/06/2010, 12:35
Una preguntilla, tmb podemos subir a este hilo cosas que hayamos hecho de ROM-Hacking?

^OMAP-Cranck^
22/06/2010, 12:59
Están muy bien los ejemplos, voy a ver si me empapo del ensamblador de la GBA y meidante el devkitPRO consigo compilar algo jugoso :babea:.

Bueno pues como me gustaria empezar a contribuir en algo a este hilo, os dejo una ROM realizada por un grupo de desarrollo del GBADEV que usa la libreria TONC llamada "Elements of DarkNess". No esta completa, pero tiene un nivel y calidad buenismos.

jduranmaster
22/06/2010, 13:39
Están muy bien los ejemplos, voy a ver si me empapo del ensamblador de la GBA y meidante el devkitPRO consigo compilar algo jugoso :babea:.

Bueno pues como me gustaria empezar a contribuir en algo a este hilo, os dejo una ROM realizada por un grupo de desarrollo del GBADEV que usa la libreria TONC llamada "Elements of DarkNess". No esta completa, pero tiene un nivel y calidad buenismos.

respecto al ROM Hacking supongo que no habría problemas, aunque no lo se seguro, es decir, no se si hay limitación en cuanto a si suib r software original pirateado a esta página.

Me encanta el Elements Of DarkNess, lo estoy jugando ahora mismo en el VisualBoy Advance. Si alguien puede, que lo pruebe en un FlashCart para GBA, que no tengo la mia a mano por aqui ahora mismo.SALUDOS.:awesome:

^OMAP-Cranck^
22/06/2010, 14:55
Sino hay problemas en subir Rom Hacking, podria subir una del Pokemon Ruby que tengo hecha. Esto se debe preguntar a algún moderador del foro, pero como soy nuevo no conozco a ninguno.

3L_S4N70
22/06/2010, 16:06
Sino, lo que puedes hacer es subir el parche para modificar la original, eso sí que no tiene porque ser problemático. Seguramente subir la ROM aunque modificada, vaya en contra de las normas (incluso de la ley) por utilizar software con copyright.

Un saludo

GameMaster
22/06/2010, 16:29
Esta disponible el src de elements of darkness ?

^OMAP-Cranck^
22/06/2010, 16:33
Sino, lo que puedes hacer es subir el parche para modificar la original, eso sí que no tiene porque ser problemático. Seguramente subir la ROM aunque modificada, vaya en contra de las normas (incluso de la ley) por utilizar software con copyright.

Un saludo

Ok, pues entonces ya subire el parche y pequeño tutorial explicando como parchear la ROM. gracias.:awesome:


Esta disponible el src de elements of darkness ?

ojala. Estube mirando pero en esa página no estaba. Porque te molaria portarlo a Wiz, o quizas terminar el trabajo?. La verdad es que es junto con el port del Another Wolrd, de lo mejor en HomeBrew que existe para la GBA.:awesome:

^OMAP-Cranck^
22/06/2010, 19:24
Bueno, pues después de leer algunas cosas sobre el ARM os dejo mi primer contribuciñon propia a este hilo. Se trata de un ejemplo realizado en el lenguaje de ensamblador para el ARM de la GameBoy Advance. Usel juego de instrucciones más simple, y no me he metido con las instrucciones del juego THUMB. El ejemplo esta compilado usando la herramienta arm-eabi-as del devkitPRO para GBA.




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

main: @ comienzo del programa principal.
mov r0, #0x4000000 @cargamos al registro R0 el valor 0x4000000.
@este valor es la direccion del controlador LCD (REG_DISPCNT).
mov r1, #0x400 @cargamos al registro R1 el valor 0x400.
add r1, r1, #3 @sumamos al contenido del registro R1 3, ahora tenemos en R1 0x403.
str r1, [r0] @escribimos el dato del registro R1 en la posición de memoria de R0

mov r0, #0x6000000 @cargamos en R0 la direccion de comienzo de la VRAM.
mov r1, #0xFF @cargamos en R1 el color a pintar en la pantalla.
mov r2, #0x9600 @cargamos en R2 el dato 0x9600

bucle:
strh r1, [r0], #2 @cargamos en la direccion de R0 el dato en R1 y luego le sumamos 2
subs r2, r2, #1 @restamos al valor del registro R2 1
bne bucle @si el bit de estado no indica el valor cero en r2 entonces volvemos
@al comienzo del bucle y se repiten los pasos anteriores.

infin: @bucle infinito
b infin




el ejemplo hace lo mismo que uno de los primeros ejemplos de jduranmaster, es decir, rellena la pantalla con un color. espero que os sirva de algo. SAYONARA.

jduranmaster
22/06/2010, 22:05
que wapo, el primer ejemplo de ensamblador para la GBA. me mola.:awesome:

^OMAP-Cranck^
23/06/2010, 15:33
Estuve leyendo nuevos tutoriales del ensamblador de la GBA y os vuelvo a subir el ejemplo anterior modificado. Resulta que la ROM que subi la vez anterior la probé en el VisualBoy Advance, pero como no tenía tiempo no la pude probar en el FlashCart para GBA. Hoy me he puesto a probarla y resulta que no funionaba. Revisando el hilo me di cuenta de que jduranmaster comentaba en un post que es necesario utilizar la herramienta "GBAFIX" que se incluye en la distribución del devkitPRO de GBA para poder formatear la cabecera de la ROM generada con información correcta. Después de hacerlo, la ROM seguía sin funcionar. Bueno pues resulta que es necesario (al menos cuando desarrollamos con el ensamblador de la GBA) indicar explicitamente que dejamos un espacio de memoria reservado para completar la cabecera de la ROM. Os dejo el código fuente en ensamblador con la modificación (son solo dos instrucciones nuevas):




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

b 0xC0 @mediante estas dos intrucciones no aseguramos que dejamos un espacio dedicado
.org 0xC0 @a rellenar la cabecera de la ROM generada con la información que podemos definir
@mediante la herramienta GBAFIX que se incluye en el devkitPRO.

main: @ comienzo del programa principal.
mov r0, #0x4000000 @cargamos al registro R0 el valor 0x4000000.
@este valor es la direccion del controlador LCD (REG_DISPCNT).
mov r1, #0x400 @cargamos al registro R1 el valor 0x400.
add r1, r1, #3 @sumamos al contenido del registro R1 3, ahora tenemos en R1 0x403.
str r1, [r0] @escribimos el dato del registro R1 en la posición de memoria de R0

mov r0, #0x6000000 @cargamos en R0 la direccion de comienzo de la VRAM.
mov r1, #0xFF @cargamos en R1 el color a pintar en la pantalla.
mov r2, #0x9600 @cargamos en R2 el dato 0x9600

bucle:
strh r1, [r0], #2 @cargamos en la direccion de R0 el dato en R1 y luego le sumamos 2
subs r2, r2, #1 @restamos al valor del registro R2 1
bne bucle @si el bit de estado no indica el valor cero en r2 entonces volvemos
@al comienzo del bucle y se repiten los pasos anteriores.

infin: @bucle infinito
b infin



También os dejo el .bat que es necesario ejecutar para que todo vaya sobre ruedas:




path=C:\devkitPro\devkitARM\bin

arm-eabi-as -o rom2.o rom2.S
arm-eabi-objcopy -O binary rom2.o ASSEMBLER_ROM2.gba

gbafix ASSEMBLER_ROM2.gba -p -tASSEMBLER_ROM -c1111 -mAR -v1

@ECHO OFF

del *.o



obviamente los parámetros del comando GBA FIX me los he inventado, ya que puede ser la información que nos de la gana. SAYONARA.

xzakox
23/06/2010, 16:37
Creo que estaría bien comentar un poco los valores del programa. Por ejemplo, porque metes 0x400 en r1 y luego le sumas 3. Esto es porque la instrucción mov de arm, si queremos cargar un inmediato (un número) en un registro, este número tiene que ser un byte, o un número que se pueda obtener de desplazar un byte. Asi podriamos poner del 0 al 255 (1 byte) y luego desplazamientos de estos a la izquierda. En un desplazamiento se añaden ceros binarios a la izquierda, por lo que es imposible obtener el 0x403. Asi que cargamos el 0x400 (pasadlo a binario para ver como se puede obtener con un desplazamiento) y luego le sumamos 3 para tener en r1 el valor 0x403. Un rollo, pero es asi. ¿Y por qúe 0x403? Es el modo... modo 3 y activado del fondo 2. :-)

Y luego por ejemplo, cuando cargamos el 0x9600... En decimal es 38400... y eso es? 240x160... la cantidad de pixeles de la pantalla que vamos a llenar de rojo. :-)

^OMAP-Cranck^
23/06/2010, 16:44
ok. gracias por completar. Tampoco se hasta que punto hay cosas que pueden ser obviedades y cosas que hacen falta ser explicadas.

xzakox
23/06/2010, 16:47
Hombre, el tema de la carga de inmediatos en arm, no es nada obvio, de hecho es bastante raro, no conozco otra plataforma donde no puedas cargar cualquier inmediato en un registro.

^OMAP-Cranck^
23/06/2010, 16:52
ok pues. intentaré ser ser más explicito en los detalles.:awesome:

Por cierto xzakox, estaba siguiendo el tuto de GameBoy, y tengo una duda: he leido en el hilo que a parte del kit en ensamblador que estás usando hay otro que es C. Es igual de potente o tiene más limitaciones que el de ensamblador (a sabida cuenta de que el lenguaje máquina siempre irá más rápdio).

xzakox
23/06/2010, 16:59
El GBDK está bien. El problema es que hace mucho que el desarrollador lo abandonó, y arrastra algun bug que te puede volver loco (sobretodo cuando empiezas a trabajar con bancos de memoria). Por lo demás bueno, las librerias están bien, pero ocupan mucho espacioy el rendimiento pues claro, es mucho menor que en ensamblador. Aun así se pueden hacer cosas muy decentes en GBDK y hay grandes juegos y apps homebrew desarrollados sobre él. Yo mismo he hecho cosillas y salvo cuando empiezas con problemas con el banking, está bastante bien.

^OMAP-Cranck^
23/06/2010, 17:01
Es bueno saberlo, porque estaba tmb viendo la posibilidad de bajarmelo y trastear con él un poco.

jduranmaster
23/06/2010, 23:33
Bueno chicos, estoy terminando de generar la nueva versión del programa Java que comnce para autogenerar los ficheros de cabecera a incluir en los poyectos de GBA a partir de imagenes en formatos JPG, BMP, PCX, etc. Tmb estoy preparando un mini tutorial con la aplicación de MP3 para GBA que nos paso Allen_S. PRoximamente lo subire todo por aqui.

SALUDOS.:awesome:

^OMAP-Cranck^
24/06/2010, 17:11
Alguien ha conseguido probar mi ultimo ejemplo en un FlashCart para GBA?, os ha funcionado?

jduranmaster
24/06/2010, 17:19
Bueno pues aqui os traigo la utlima versión del HeaderGenrator realizada en Java (aun en fase de pruebas) que nos permite hacer la conversión de una imagen a un fichero .h de cabecera en lenguaje C. Los datos de la imagen son almacenados en el tipo generado por la herramienta PCX2GBA. Lo bueno de mi versión es que no necesitamos convertir la imagen a PCX para poder obtener un fichero .h que podamos usar en nuestros proyectos ya sea con el devkitPRO o bien usando el devkitadv. La herramienta actualmente soporta los formatos PNG, JPEG y BMP.

Aqui os pongo el código fuente:




/*
@author: jduranmaster
@version: 1.0
*/

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;

import java.io.FileWriter;
import java.io.PrintWriter;

import java.io.FileInputStream;
import java.io.InputStream;

import javax.imageio.ImageIO;

/**
Este programa nos va a permitir convertir de forma sencilla cualquier formato gráfico a un fichero de cabecera.h de lenguaje
de programación C donde se encuentran los datos de la imagen convertida a tipo USHORT, que es equivalente al USHORT que
genera la aplicación PCX2GBA. USHORT y u16 (tipo usado en el devkitPRO) son del tipo "UNSIGNED SHORT".
(De momento esta versión funciona perfectamente con los formatos JPEG, PNG y BMP)
*/

public class HeaderGenerator{
public static final int PIXEL_ROW_WIDTH = 40;

public static void main(String[] args) {
try {
java.lang.String prefix = "exportedtiles";
if (args.length > 2)
prefix = args[2];
//creamos el flujo de salida que usaremos para escribir en el fichero de cabecera .h de lenguaje de programación C
//que podemos especificar en la linea de mandatos. El nombre del fichero .h es obligatorio.
java.io.PrintWriter pw = new PrintWriter(new FileWriter(args[1]));
//creamos el flujo de entrada que usaremos para leer del fichero de imagen que podemos especificar en la linea de
//mandatos. El nombre del fichero de imagen es obligatorio.
java.io.InputStream is = new java.io.FileInputStream(args[0]);
java.awt.image.BufferedImage img = javax.imageio.ImageIO.read(is);
//empezamos a escibir en el fichero de cabecera .h los datos básicos.
pw.println("/*@author: jduranmaster*/");
pw.println("/*@version: 1.0*/");
pw.println();
//aqui escribimos en el fichero de salida el ancho y el alto de la imagen.
//Como sabemos la GameBoy Advance admite imagenes de 240x160, por tanto no podemos continuar con las oiperaciones
//a no ser que las propiedades de la imagen nos indiquen que fectivamente tenemos una imagen de ese tamaño
//o bien que sea de un tamaño menor.
if((img.getWidth() <= 240) && (img.getHeight() <= 160)){
//añadimos los defines al comienzo del fichero de cabecera .h
pw.println("#ifndef " + "__" + prefix + "__");
pw.println("#define " + "__" + prefix + "__");
//definimos dos contantes que especifican el alto y ancho de la imagen. Estan tomados de las propiedades de la
//propia imagen de entrada al programa.
pw.println("#define " + prefix + "_WIDTH " + img.getWidth());
pw.println("#define " + prefix + "_HEIGHT " + img.getHeight());
pw.println();
//indexed byte image. Al utilizar este tipo estamos usando una paleta cúbica de colores con el formato 256 6/6/6
if (img.getType() == java.awt.image.BufferedImage.TYPE_BYTE_INDEXED) {
java.awt.image.ColorModel m = img.getColorModel();
// Obtenemos los valores de la paleta y vamos escribiendo en el fichero de cabecera .h
//y generamos una estrutura para la paleta dentro del fichero de cabecera .h
pw.println("const USHORT " + prefix + "Palette[] = {");
for (int i = 0; i < 256; i++) {
int red = (m.getRed(i) >> 3);int green = (m.getGreen(i) >> 3);
int blue = (m.getBlue(i) >> 3);short rgb = (short) (red | (green << 5) | (blue << 10));
pw.print("\t0x" + Integer.toHexString(rgb));if (i < 255){pw.println(",");}
}
pw.println("};");
pw.println();
// Y a continuación escribimos los valores de los pixels de la imagen mediante una estructura
//definida como USHORT.
DataBuffer buffer = img.getData().getDataBuffer();pw.print("const USHORT " + prefix + "data[] = {");
int n = buffer.getSize();int i;
for (i = 0; i < n; i += 2) {
if ((i % PIXEL_ROW_WIDTH) == 0){pw.println();}
int pixel = (buffer.getElem(i) | (buffer.getElem(i + 1) << 8));
pw.print("0x" + Integer.toHexString(pixel));if (i < (n - 2)){pw.print(", ");}
}
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}
else{
//si el tipo de imagen no se ajusta el tipo "TYPE_BYTE_INDEXED" aplicamos una receta distinta.
//cargamos directamente los valores de los pixeles en el fichero .h
pw.println("const USHORT " + prefix + "data[] = {");
int width = img.getWidth();int height = img.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = img.getRGB(x, y);int red = ((pixel >> 16) & 0x0000FF) >> 3;
int green = ((pixel >> 8) & 0x0000FF) >> 3;int blue = (pixel & 0x0000FF) >> 3;
short rgb = (short) (red | (green << 5) | (blue << 10));
pw.print("0x" + Integer.toHexString(rgb));
if ((x < (width - 1)) || (y < (height - 1))){pw.print(", ");}
}
}pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
pw.println("};");
pw.println();
pw.println("#endif");
pw.println("");
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}else{
System.err.println("La Imagen de entrada no puede tener un tamaño superior a 240x160.");
}
}catch(java.io.IOException ioe){
System.err.println("Fichero de Imagen no Encontrado");
}catch (Exception e) {
System.err.println("Syntaxis: java HeaderGenerator fichero_imagen fichero_h [prefijo_opcional]");
}
}//fin del metodo main.
}//fin de la clase.



Para probar que realmente funciona he cogido un fichero BMP y lo he exportado a .h. Luego empleando el devkitadv he generado un mini proyecto para generar una rom que muestre esa imagen por pantalla. El código del programa principal en este caso es:





/*
author: jduranmaster
*/

#include "base.h"
#include "m.h"

USHORT* ScreenBuffer = (USHORT*)0x6000000;//comienzo de la VRAM.

int main(){
USHORT loop;

SetMode(MODE3 | BG2_ENABLE);//seleccionamos el modo gráfico (MODO 3)
//background 2

for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = exportedtilesdata[loop];
}

//con el bucle cargamos en el buffer de pantalla los datos de la imagen.

while(1){}
}//fin de main



Este mismo ejemplo ya lo subi anteriormente y no deberia haber problemas en entender su funcionamiento. Finalmente pasamos a la rom generada, la herramienta GBAFIX y ya tenemos nuestra rom lista para funcionar en un FLASHCART para GBA. Lo he testado y la rom funciona perfectamente. Asi que ya tenemos HERRAMIENTA NUEVA!!!!!!!!:awesome:

xzakox
24/06/2010, 17:34
Mola, mola :D

Estaría bien poder especificarle en línea de parámetros el prefix que quieres, por si usas varias imágenes en el mismo proyecto, u obtenerlo del nombre del fichero h que le pasas de parámetro (quitando la extensión). Veo que también empiezas a escribir en el archivo (los comentarios iniciales) y luego compruebas el tamaño de la imagen, ¿no sería mejor hacerlo antes de escribir nada?
Por cierto, la gameboy advance pilla o un modo de 8 bits o de 16 bits de color, estaría bien comprobar que las imágenes que le pasas estén en uno de esos dos modos.


Por lo demás genial, la gente usaba el pcx porque es fácil de leer y tal, pero teniendo librerias gráficas de abstracción como hoy en dia, pues ya hacia falta alguna herramienta asi.

jduranmaster
24/06/2010, 17:43
me alegro de que os mole. Las mejoras que comentas las hire incluyendo poco a poco para que quede mas completa. SALUDOS.:awesome:

^OMAP-Cranck^
24/06/2010, 21:31
que grande el programa de conversión. espero que me de tiempo a terminar nuevos ejemplos del ensamblador del ARM para subirlos por aqui. Una pregunta: alguien sabe donde conseguir el SDK HAM para GBA? :awesome:

jduranmaster
24/06/2010, 22:09
gracias colega.:awesome:. Te podrías currar algún ejemplo con instrucciones del set Thumb del ARM.........:awesome:

^OMAP-Cranck^
24/06/2010, 22:22
gracias colega.:awesome:. Te podrías currar algún ejemplo con instrucciones del set Thumb del ARM.........:awesome:

de hecho uno de los ejemplos que estoy haciendo hace uso de el. Ya os comentaré porque tengo un problemilla con uno de los programas. Me explico lo que quiero que haga el programa funciona con instrucciones del set thumb pero no con el juego básico del ARM, y teóricamente debería funcionar aunque esten implementados usando juegos distintos.

Con respecto a la pregunta de antes, alguien sabe donde pillar el kit de desarrollo HAM para GBA?

jduranmaster
24/06/2010, 23:37
pues el HAM no se donde conseguirlo, y mira que lo estuve buscando, erpo di con unos enlaces que se reseteaban y no te dejaban terminar la descarga, lo mismo era porque en la página en cuestión se ncesitaba estar registrado, pero ya no lo recuerdo bien.

Espero ver esos ejemplos para el ARM pronto colega.:awesome:

tanuquillo
25/06/2010, 00:20
hay modulos de musica de gb?
por ejemplo yo pillo la rom del zelda y la cargo como si fuera un midi y que me saque todas las musicas?

jduranmaster
25/06/2010, 10:36
hay modulos de musica de gb?
por ejemplo yo pillo la rom del zelda y la cargo como si fuera un midi y que me saque todas las musicas?

modulos ya hechos no lo se, lo que si que tienes son los registros para controlar el sonido en GB y tmb en GBA. a ver si saco un poco de tiempo y termino uno de los ejemplos para hacer sonar mod en gba, que ya me contesto ayer uno de los desarrolladores del Apex Audio System y tengo la libreria completa para GBA.:awesome:

^OMAP-Cranck^
25/06/2010, 12:03
he estado mirando el set de intrucciones de thumb y aqui dejo un ejemplo de cabecera de fichero en ensamblador. El tema es que para pasar de un set de instrucciones a otro, no basta con emepzar a escribir instrucciones THUMB y dejar que la cosa vaya sola:




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

b 0xC0

.org 0xC0
main_ARM:
mov r0, #0x08000000 @con estas instrucciones hacemos el cambio de
add r0, r0, #0xE1 @ de un set a otro.
bx r0

.thumb
.thumb_func
.align 2

.org 0xE0

main:
@aqui es donde colocamos el código haciendo uso de instrucciones THUMB.
infin:
b infin



sigo investigando........

^OMAP-Cranck^
25/06/2010, 13:23
bueno pues después de bajarme un pdf donde viene más o menos explicado algunas intrucciones del set THUMB he conseguido hacer el mismo ajemplo que subi antes pero usando las instrucciones del set THUMB y en lugar de pintar en color rojo la pantalla le indicamos que lo haga en un tono de marrón: 0xAF (registro R2). aqui está el código:




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

start:
b 0xC0


.org 0xC0
mov r0, #0x08000000 @con estas instrucciones indicamos que vamos a pasar a hacer
add r0, r0 ,#0xE1 @uso del set de intrucciones THUMB. Una cosa interesante a recalcar, es que
bx r0 @las instrucciones del set THUMB ocupan dos bytes en lugar de 4 bytes como
@ocurre con las instrucciones del set básico de ARM. Esto aspecto es
@es muy interesante porque nos permite hacer programas usando el set THUMB que
@ocupen menos espacio.

.thumb @ya entramos en el juego de instrucciones THUMB.
.thumb_func
.align 2

.org 0xE0

main:
mov r0, #0x80 @r0 = 0x80 lsl 0x13 = 0x04000000
lsl r0, r0, #0x13 @r0 = 0x04000000, es decir estás instrucciones son equivalentes a hacer
@ mov r0, #0x4000000 usando el set de ARM.
mov r1, #0x80 @r1 = 0x40 lsl 0x4 = 0x400
lsl r1, r1, #0x3
add r1, r1, #0x3 @r1 = #0x403 es decir empleamos el modo 3 y activamos el fondo 2.
str r1, [r0]

mov r0, #0xC0
lsl r0, r0, #0x13 @r0 = 0x06000000, con esto estamos cargando el registro R0 la dirección de
@comienzo de la VRAM.
mov r1, #0x96
lsl r1, #0x8 @r1 = 0x9600, finalmente indicamos en el registro R1 la cantidad de pixeles
@que vamos a rellenar usando el color marron, que en este caso son 240x160.
mov r2, #0xAF @cargamos el color marron en el registro R2.

bucle:
strh r2, [r0] @cargamos en la direccion de R0 el dato en R1 y luego le sumamos 2
add r0, #0x2
sub r1, #1 @restamos al valor del registro R2 1
cmp r1, #0x0 @si el bit de estado no indica el valor cero en r1 entonces volvemos
@al comienzo del bucle y se repiten los pasos anteriores.
bne bucle


infin: @bucle infinito
b infin



para compilar usando el devkitPRO seguimos los pasos siguientes:




path=C:\devkitPro\devkitARM\bin

arm-eabi-as -o romTHUMB.o romTHUMB.S
arm-eabi-objcopy -O binary romTHUMB.o ASSEMBLER_THUMB_ROM.gba

gbafix ASSEMBLER_THUMB_ROM.gba -p -tASSEMBLER_ROM -c1111 -mAR -v1

@ECHO OFF

del *.o



ahora estoy intentando ver como podemos hacer para que nos pinte una imagen por pantalla usando el set de instrucciones de THUMB. A ver si hay suerte. SAYONARA.:awesome:

^OMAP-Cranck^
25/06/2010, 18:46
bueno pues después de leer el PDF, he conseguido sacar otro programilla para poder sacar por la pantalla de la GBA una imagen (es igual que el ejemplo de jduranmaster del comienzo del hilo pero hecho con ensamblador del ARM). Una vez más he empleado instrucciones del set de THUMB. Estuve probando con el set básico del ARM pero tengo problemas a la hora cargar la imagen si quereis puedo subir ese código y lo comentamos a ver donde puede estar la solución.El código fuente del programa que emplea el set de instrucciones THUMB es el siguiente:




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

start:
b 0xC0

.org 0xC0
mov r0, #0x08000000 @con estas instrucciones indicamos que vamos a pasar a hacer
add r0, r0 ,#0xE1 @uso del set de intrucciones THUMB. Una cosa interesante a recalcar, es que
bx r0 @las instrucciones del set THUMB ocupan dos bytes en lugar de 4 bytes como
@ocurre con las instrucciones del set básico de ARM. Esto aspecto es
@es muy interesante porque nos permite hacer programas usando el set THUMB que
@ocupen menos espacio.

.thumb @ya entramos en el juego de instrucciones THUMB.
.thumb_func
.align 2

.org 0xE0

main:
mov r0, #0x80 @r0 = 0x80 lsl 0x13 = 0x04000000
lsl r0, r0, #0x13 @r0 = 0x04000000, es decir estás instrucciones son equivalentes a hacer
@ mov r0, #0x4000000 usando el set de ARM.
mov r1, #0x4
lsl r1, r1, #0x8
add r1, r1, #0x3 @r1 = 0x403
strh r1, [r0] @r1 = #0x403 es decir empleamos el modo 3 y activamos el fondo 2.

ldr r0, =imagen @cargamos los datos de la imagen en el registro R0.
mov r1, #0x80
lsl r1, #0x14
add r0, r1, r0
mov r1, #0xC0
lsl r1, r1, #0x13 @r0 = 0x06000000, con esto estamos cargando el registro R0 la dirección de
@comienzo de la VRAM.
mov r2, #0x96 @r1 = 0x9600, indicamos en el registro R1 la cantidad de pixeles 240x160.
lsl r2, r2, #0x7 @la instrucción SWI usa escrituras de 32 bits. r2 = 0x12C00 / 4 = 0x4B00
swi 0xC

infin: @bucle infinito.
b infin

.ltorg @usado para la ldr r0, =imagen. LTORG nos permite ensamblar el código binario de la imagen
@que hemos incluido dentro de la sección de código de nuestro programa.
imagen:
.incbin "mega2.bin"



yo lo he compilado con el devkitPRO usando las sentencias siguientes en un fichero de proceso por lotes:




path=C:\devkitPro\devkitARM\bin

arm-eabi-as -o rom3.o rom3.S
arm-eabi-objcopy -O binary rom3.o ASSEMBLER_ROM3.gba

gbafix ASSEMBLER_ROM3.gba -p -tASSEMBLER_ROM -c1111 -mAR -v1

@ECHO OFF

del *.o



ahora lo que estoy probando es hacer lo mismo pero con varias imagenes y usando el PAD de la GBA. Pero como esta tarde juega España, me da a mi que mejor me voy a beber algo y a ver el partido que desde aqui es dificil pillar la señal.SAYONARA.:awesome:

jduranmaster
25/06/2010, 20:54
molan los ejemplos de ensamblador para la GBA. a ver si tengo un rato y los pruebo.

tSuKiYoMi
25/06/2010, 21:05
como mola, me ausento un par de dias y hay un monton de homebrew nuevo que probar. Todos los ejemplos de ensamblador para la GBA están compilados usando el devkitPRO?

xzakox
26/06/2010, 04:31
Bueno, acabo de terminar un ejemplo que usa dos bancos de ROM diferentes para guardar codigo (en direcciones mayores a los 32KB), y además usa la SRAM externa para guardar datos (la que se usa para los cartuchos que graban partida). Además he añadido subrutinas de impresión de texto, y usando parte del código Java de la herramienta de jduranmaster, he creado una herramienta para convertir imagenes en un determinado formato, a archivos de datos para crear fuentes de texto para la gameboy.
Es muy tarde asi que ahora me voy a dormir, mañana lo subo todo con las explicaciones.
:-)

jduranmaster
26/06/2010, 11:02
ya he probado tus roms OMAP, y de momento todas funcionan bien en el FlashCart de GBA. SALUDOS.:awesome:

xzakox
26/06/2010, 11:54
Ahi teneis el siguiente ejemplo con su explicación:
http://wiki.ladecadence.net/doku.php?id=tutorial_de_ensamblador#hola_bancos

Luego subo el programa para generar fuentes.
Un saludo.

jduranmaster
26/06/2010, 11:58
Bueno, pues aqui subo una versión nueva del HeaderGenerator realizado en java. He modificado el programam para que se pueda incluir en la linea de mandatos el tipo de prefijo para generar multiples ficheros de cabecera .h de lenguaje C con prefijos distintos, para cuando usemos en nuestro proyecto imagenes distintas.




/*
@author: jduranmaster
@version: 1.0
*/

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;

import java.io.FileWriter;
import java.io.PrintWriter;

import java.io.FileInputStream;
import java.io.InputStream;

import javax.imageio.ImageIO;

/**
Este programa nos va a permitir convertir de forma sencilla cualquier formato gráfico a un fichero de cabecera.h de lenguaje
de programación C donde se encuentran los datos de la imagen convertida a tipo USHORT, que es equivalente al USHORT que
genera la aplicación PCX2GBA. USHORT y u16 (tipo usado en el devkitPRO) son del tipo "UNSIGNED SHORT".
(De momento esta versión funciona perfectamente con los formatos JPEG, PNG y BMP)
*/

public class HeaderGenerator{
public static final int PIXEL_ROW_WIDTH = 40;

public static void main(String[] args) {
try {
//podemos seleccionar el tipo de prefijo que queremos usar. En caso de que no se especificque ninguno
//tomamos por defecto el prefijo "exportedtiles"
java.lang.String prefix = "exportedtiles";
if (args.length > 2)
prefix = args[2];
//creamos el flujo de salida que usaremos para escribir en el fichero de cabecera .h de lenguaje de programación C
//que podemos especificar en la linea de mandatos. El nombre del fichero .h es obligatorio.
java.io.PrintWriter pw = new PrintWriter(new FileWriter(args[1]));
//creamos el flujo de entrada que usaremos para leer del fichero de imagen que podemos especificar en la linea de
//mandatos. El nombre del fichero de imagen es obligatorio.
java.io.InputStream is = new java.io.FileInputStream(args[0]);
java.awt.image.BufferedImage img = javax.imageio.ImageIO.read(is);
//empezamos a escibir en el fichero de cabecera .h los datos básicos.
pw.println("/*@author: jduranmaster*/");
pw.println("/*@version: 1.0*/");
pw.println();
//aqui escribimos en el fichero de salida el ancho y el alto de la imagen.
//Como sabemos la GameBoy Advance admite imagenes de 240x160, por tanto no podemos continuar con las operaciones
//a no ser que las propiedades de la imagen nos indiquen que fectivamente tenemos una imagen de ese tamaño
//o bien que sea de un tamaño menor.
if((img.getWidth() <= 240) && (img.getHeight() <= 160)){
//añadimos los defines al comienzo del fichero de cabecera .h
pw.println("#ifndef " + "__" + prefix + "__");
pw.println("#define " + "__" + prefix + "__");
//definimos dos contantes que especifican el alto y ancho de la imagen. Estan tomados de las propiedades de la
//propia imagen de entrada al programa.
pw.println("#define " + prefix + "_WIDTH " + img.getWidth());
pw.println("#define " + prefix + "_HEIGHT " + img.getHeight());
pw.println();
//indexed byte image. Al utilizar este tipo estamos usando una paleta cúbica de colores con el formato 256 6/6/6
if (img.getType() == java.awt.image.BufferedImage.TYPE_BYTE_INDEXED) {
java.awt.image.ColorModel m = img.getColorModel();
// Obtenemos los valores de la paleta y vamos escribiendo en el fichero de cabecera .h
//y generamos una estrutura para la paleta dentro del fichero de cabecera .h
pw.println("const USHORT " + prefix + "Palette[] = {");
for (int i = 0; i < 256; i++) {
int red = (m.getRed(i) >> 3);int green = (m.getGreen(i) >> 3);
int blue = (m.getBlue(i) >> 3);short rgb = (short) (red | (green << 5) | (blue << 10));
pw.print("\t0x" + Integer.toHexString(rgb));if (i < 255){pw.println(",");}
}
pw.println("};");
pw.println();
// Y a continuación escribimos los valores de los pixels de la imagen mediante una estructura
//definida como USHORT.
DataBuffer buffer = img.getData().getDataBuffer();pw.print("const USHORT " + prefix + "data[] = {");
int n = buffer.getSize();int i;
for (i = 0; i < n; i += 2) {
if ((i % PIXEL_ROW_WIDTH) == 0){pw.println();}
int pixel = (buffer.getElem(i) | (buffer.getElem(i + 1) << 8));
pw.print("0x" + Integer.toHexString(pixel));if (i < (n - 2)){pw.print(", ");}
}
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}
else{
//si el tipo de imagen no se ajusta el tipo "TYPE_BYTE_INDEXED" aplicamos una receta distinta.
//cargamos directamente los valores de los pixeles en el fichero .h
pw.println("const USHORT " + prefix + "data[] = {");
int width = img.getWidth();int height = img.getHeight();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = img.getRGB(x, y);int red = ((pixel >> 16) & 0x0000FF) >> 3;
int green = ((pixel >> 8) & 0x0000FF) >> 3;int blue = (pixel & 0x0000FF) >> 3;
short rgb = (short) (red | (green << 5) | (blue << 10));
pw.print("0x" + Integer.toHexString(rgb));
if ((x < (width - 1)) || (y < (height - 1))){pw.print(", ");}
}
}pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
pw.println("};");
pw.println();
pw.println("#endif");
pw.println("");
pw.flush();//obligamos al buffer de escritura a escribir lo que le falte en el fichero .h
}else{
System.err.println("La Imagen de entrada no puede tener un tamaño superior a 240x160.");
}
}catch(java.io.IOException ioe){
System.err.println("Fichero de Imagen no Encontrado");
}catch (Exception e){
System.err.println("Syntaxis: java HeaderGenerator fichero_imagen fichero_h [prefijo_opcional]");
}
}//fin del metodo main.
}//fin de la clase.




para probar que funcionaba bien me he hecho otra rom en la que podemos cambiar la imagen presente en la pantalla de la GBA pulsando las teclas del PAD. En el ejemplo uso el modo gráfico 3 y fondo activo 2.El código fuente del programa principal es el siguiente:




/*
author: jduranmaster
*/

#include "keypad.h" //definiciones del keypad.
#include "base.h" //definiciones de los tipos de datos que usa el devkitadv.
#include "cowboy1.h" //bytes de la imagen 1 obtenidos con la herramienta HeaderGenerator.
#include "cowboy2.h" //bytes de la imagen 2 obtenidos con la herramienta HeaderGenerator.
#include "cowboy3.h" //bytes de la imagen 3 obtenidos con la herramienta HeaderGenerator.
#include "cowboy4.h" //bytes de la imagen 4 obtenidos con la herramienta HeaderGenerator.
#include "cowboy5.h" //bytes de la imagen 5 obtenidos con la herramienta HeaderGenerator.
#include "cowboy7.h" //bytes de la imagen 6 obtenidos con la herramienta HeaderGenerator.
#include "cowboy8.h" //bytes de la imagen 7 obtenidos con la herramienta HeaderGenerator.
#include "cowboy9.h" //bytes de la imagen 8 obtenidos con la herramienta HeaderGenerator.
#include "cowboy10.h" //bytes de la imagen 9 obtenidos con la herramienta HeaderGenerator.
#include "cowboy11.h" //bytes de la imagen 10 obtenidos con la herramienta HeaderGenerator.
#include "cowboy12.h" //bytes de la imagen 11 obtenidos con la herramienta HeaderGenerator.

USHORT* ScreenBuffer = (USHORT*)0x6000000;

int main(){
USHORT loop;

SetMode(MODE3 | BG2_ENABLE);//seleccionamos el modo gráfico (MODO 3)

//fijamos la imagen que aparecerá cuando se cargue la ROM por primera vez.
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy10data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.

while (1) // bucle infinito
{
// process input
if(!((*KEYS) & KEY_A)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy1data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_B)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy3data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_SELECT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy5data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_START)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy2data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_R)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy4data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_L)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy7data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_UP)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy8data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_DOWN)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy9data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_LEFT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy11data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
if(!((*KEYS) & KEY_RIGHT)){
for(loop=0;loop<38400;loop++) {
ScreenBuffer[loop] = cowboy12data[loop];
}//con el bucle cargamos en el buffer de pantalla los datos de la imagen.
}
}
}//fin de main




El proyecto esta compilado usando el devkitADV, y la cabecera de la ROM ya esta formateada correctamente usando el GBAFIX. SALUDOS.:awesome:

^OMAP-Cranck^
26/06/2010, 12:50
gracias por probar mis roms anteriores jduranmaster.:awesome:

^OMAP-Cranck^
26/06/2010, 13:18
Os dejo un ejemplo en ensamblador para el ARM de la GBA. Se trata de un ejemplo compilado con el devkitPRO. En el hago uso de los Timers. Básicamente pinta por pantalla el color rojo y tras 6 segundos cambia al color verde. Logicamente la cuenta la he realizado usando los timers. Aqui pongo el código fuente:




.arm @indicamos al ensamblador que usamos intrucciones ARM.
.text @indicamos que todo lo escrito a continuacion se incluye en la seccion del codigo.
.global main @indicamos al ensamblador que tiene acceso a nuestro programa principal, de esta forma
@el linkador podra encontrar el programa principal.

start:
b 0xC0


.org 0xC0
mov r0, #0x08000000 @con estas instrucciones indicamos que vamos a pasar a hacer
add r0, r0 ,#0xE1 @uso del set de intrucciones THUMB. Una cosa interesante a recalcar, es que
bx r0 @las instrucciones del set THUMB ocupan dos bytes en lugar de 4 bytes como
@ocurre con las instrucciones del set básico de ARM. Esto aspecto es
@es muy interesante porque nos permite hacer programas usando el set THUMB que
@ocupen menos espacio.

.thumb @ya entramos en el juego de instrucciones THUMB.
.thumb_func
.align 2

.org 0xE0

main:
mov r0, #0x80 @r0 = 0x80 lsl 0x13 = 0x04000000
lsl r0, r0, #0x13 @r0 = 0x04000000, es decir estás instrucciones son equivalentes a hacer
@ mov r0, #0x4000000 usando el set de ARM.
mov r1, #0x4 @r1 = 0x40 lsl 0x4 = 0x400
lsl r1, r1, #0x8
add r1, r1, #0x3 @r1 = #0x403 es decir empleamos el modo 3 y activamos el fondo 2.
strh r1, [r0]

@cargamos en la pantalla de la GBA el color rojo.
mov r1, #0xFF
bl rellenar

@hay que destacar que en la GBA tenemos 4 Timers de 16 bits cada uno. El límite máximo de cuenta está en 0xFFFF. Cada uno
@de los Timers emplea dos registros segun la sieguietne leyenda:

@Timer 0 Cuenta 0x04000100
@Timer 0 Control 0x04000102
@Timer 1 Cuenta 0x04000104
@Timer 1 Control 0x04000106
@Timer 2 Cuenta 0x04000108
@Timer 2 Control 0x0400010A
@Timer 3 Cuenta 0x0400010C
@Timer 3 Control 0x0400010E

@para configurar adecuandamente los Timers podemos seguir la siguiente explicacion:

@ Significado del Bit
@0-1 Valor Prescalar.
@2 Chequea el Desbordamiento (se ha alcanzado el limite de la cuenta) (0 = desactivado, 1 = activado).
@3-5 No tienen uso.
@6 Interrupcion del Timer (0 = desactivado, 1 = activado).
@7 Timer Activado (0 = desactivado, 1 = activado)
@8-15 No tienen uso.

@inicializamos los TIMERS.
mov r0, #0x80
lsl r0, r0, #0x13 @r0 = 0x04000000
add r0, r0, #0xFF
add r0, r0, #0x3 @r0 = 0x04000102, vamos a usar el Timer 0.
mov r1, #0x82 @activamos el Timer 0 | Prescalar = 2
strh r1, [r0]

add r0, r0, #0x4 @r0 = 0x04000106, vamos a usar el Timer 1.
add r1, r1, #0x2 @activamos el Timer 1 | activamos el control de desbordamiento (overflow)
strh r1, [r0]

bl esperarTimer

@rellena la pantalla con el color verde.
mov r1, #0xA0
bl rellenar

infin: @bucle infinito.
b infin

rellenar: @en R1 tenemos el color cargado previamente.
mov r0, #0xC0
lsl r0, r0, #0x13 @r0 = 0x06000000, dirección de comienzo de la VRAM.
mov r2, #0x96 @r1 = 0x9600, finalmente indicamos en el registro R1 la cantidad de pixeles
lsl r2, r2, #0x8 @que vamos a rellenar usando el color marron, que en este caso son 240x160.
add r2, r2, r2

bucle:
strh r1, [r0] @cargamos en la direccion de R0 el dato en R1 y luego le sumamos 2
add r0, r0, #0x1
sub r2, r2, #0x1 @restamos al valor del registro R2 1
cmp r2, #0x0 @si el bit de estado no indica el valor cero en r1 entonces volvemos
@al comienzo del bucle y se repiten los pasos anteriores.
bne bucle
bx lr

esperarTimer:
mov r0, #0x80
lsl r0, r0, #0x13
add r0, r0, #0xFF
add r0, r0, #0x5 @r0 = 0x04000104 (cuenta el Timer 1)

esperar:
ldrh r1, [r0]
cmp r1, #0x6
bne esperar
bx lr




Os dejo también unas capturas de pantalla usando el VisualBoy Advance y la ROM que deberia funcionar en un FlashCart de GBA (ya he usado el GBAFIX). Si quereis recompialr o modificar podeis hacerlo con un fichero de proceso por lotes con este contenido:




path=C:\devkitPro\devkitARM\bin

arm-eabi-as -o rom.o rom.S
arm-eabi-objcopy -O binary rom.o ASSEMBLER_ROM.gba

gbafix ASSEMBLER_ROM.gba -p -tASSEMBLER_ROM -c1111 -mAR -v1

@ECHO OFF

del *.o



SAYONARA.:awesome:

jduranmaster
27/06/2010, 11:13
otro ejemplo muy wapo del ensamblador del ARM.:awesome:

^OMAP-Cranck^
27/06/2010, 18:08
gracias por los animos- alguien sabe donde puedo conseguir algún tutorial wapo del GBDK?

jduranmaster
28/06/2010, 13:14
has probado a mirar en alguno del GBdev?, de todas formas seguro xzakox conoce alguno bueno.

< - >

como mola, me ausento un par de dias y hay un monton de homebrew nuevo que probar. Todos los ejemplos de ensamblador para la GBA están compilados usando el devkitPRO?

segun los datos que ha puesto OMAP, parece que si. Todos los ejemplos están compilados usando el devkitPRO. de hecho el arm-eabi es el compilador que trae de serie el devkitPRO, asi que ya sabes......

jduranmaster
30/06/2010, 17:08
aqui os dejo una prueba que he realizado con el GBa WalkMan cuyos enlaces nos dejo Allen_S para poder probar. La verdad es que el programa tiene el defecto de que la interfaz no está traducida y aparecen caracteres extraños, pero por lo demas funciona bastante bien. En principio en la misma ROM se pueden incluir hasta 20 temas en mp3 (lo que implica un tamaño de rom considerable). Yo he metido solo un tema extraido de la película: "La Muerte Tenía Un Precio". Existe otra versión del programa (la 2.0) que aun no he podido testear, cuando lo haga subire los resultados por aqui. LA ROM generada está testeada con el VisualBoy Advance, no se si funcionara en una GBA con FlashCart por el tema e las cabeceras, si alguien tiene tiempo que lo pruebe y comente que tal. Ahora estoy liado con la reproducción de MOD en GBA y espero subir dentro de poco algunos ejemplos al respecto.Que lo disfruteis, y ya sabeis, podeis usar tmb la GBA para escuchar musica!!!!!! SALUDOS.:awesome:

tSuKiYoMi
02/07/2010, 12:27
he bajado el programa de otro sitio, y la verdad da gusto hacer la conversión con el, el problema es que las roms con muchas canciones suben mucho el espacio ocupado, y no se yo si un flashvcart soportara bien roms de mas de 32 Megas.

jduranmaster
03/07/2010, 18:52
he bajado el programa de otro sitio, y la verdad da gusto hacer la conversión con el, el problema es que las roms con muchas canciones suben mucho el espacio ocupado, y no se yo si un flashvcart soportara bien roms de mas de 32 Megas.

Ese es el principal problema que yo le veo al invento, efectivamente si usas archivos en MP3 con un tamaño elevado, la rom final tmb tendra un tamaño muy grande. Por cierto alguien sabe donde se puede obtener el SDK HAM para GBA, porque ahora estoy haciendo pruebas el SDK oficial de GBA que me paso manirea, pero me gustaria tmb poder probar el SDK HAM.

^OMAP-Cranck^
06/07/2010, 22:53
una preguntilla, el HeaderGenerator que ha codificado jduran tmb se puede usar en proyectos para GameBoy?, lo pregunto porque cuando queremos hacer uso de imagenes en el modo bitmap de GB podemos hacer uso de la herramienta pcx2gb que es para desarrollar en GameBoy, aun asi no habría porblemas en usar la herramienta de jduran o solo sirve para GBA?

jduranmaster
09/07/2010, 19:18
una preguntilla, el HeaderGenerator que ha codificado jduran tmb se puede usar en proyectos para GameBoy?, lo pregunto porque cuando queremos hacer uso de imagenes en el modo bitmap de GB podemos hacer uso de la herramienta pcx2gb que es para desarrollar en GameBoy, aun asi no habría porblemas en usar la herramienta de jduran o solo sirve para GBA?

no he probado el modo bitmap de la Gameboy (de hecho hace una semana que no toco nada de esto porque estoy con el Windows Azure), pero no estoy seguro de si la herramienta pcx2GB para GameBoy genera el mismo tipo de estructura de datos para las imagenes PCX como lo hace el PCX2GA, es mas me atreveria a decir que no porque los modos bitmap de una consola y otra son distintos. En el caso de mi herramienta y del PCX2GBA (para GameBoy Advance) se genera en el caso más simple una estructura de datos deonde el tipo básico es USHORT o lo que es lo mismo, "UNSIGNED SHORT". De todas formas sería cuestión de probar pero creo que en principio no te serviria, y tendrías que tirar de pcx2gb. La autentica ventaja de mi herramienta a la hora de hacer cosas para GBA es que no necesitas cambiar el formato de la imagen de entrada a PCX ,ya que por defecto admite: BMP, JPEG, PNG.... PEro ahora que lo comentas me ha picado la curiosidad y lo mismo saco un versión nueva de mi herramienta para que tmb haga conversiones para el modo Bitmap de la GameBoy. SALUDOS.:awesome:

^OMAP-Cranck^
09/07/2010, 19:40
PEro ahora que lo comentas me ha picado la curiosidad y lo mismo saco un versión nueva de mi herramienta para que tmb haga conversiones para el modo Bitmap de la GameBoy. SALUDOS.:awesome:

pues estaria muy guapo tener una herramienta que haga la conversión tanto para GameBoy como para GameBoy Advance.:awesome:

jduranmaster
10/07/2010, 18:46
pues estaria muy guapo tener una herramienta que haga la conversión tanto para GameBoy como para GameBoy Advance.:awesome:

ahora en unas semanas espero tener más tiempo libre, asiq ue me pondre con ello. saludos.:awesome:

^OMAP-Cranck^
14/07/2010, 19:46
ok. yo la verdad es que el ensambaldor de la GBA tmb lo tenia un poco abandonado, pero queria hacer unas roms nuvas usando los timer´s como en otra que habia colgado anterioremente, pero haciendo cosas mas complicadillas.

tanuquillo
15/07/2010, 08:07
y el mitimo player de mp3 seria posible? siempre se ha dicho que no.
pero y de ogg o de wma?

GameMaster
15/07/2010, 08:21
Que yo sepa el player existe.

jduranmaster
15/07/2010, 14:01
revisa el hilo, subi una rom que permite escuchar una pista de audio en mp3 realizada con un programa cuyos enlaces solto por aqui Allen_S. El programa tiene dos versiones, aun me falta comentar los resultados del segundo programa.

saucjedi
15/07/2010, 14:14
Un player de MP3 para GBA es posible, lo que no es posible es (espacio aparte) escuchar un MP3 durante un juego porque la GBA no da para más. Pero players sí que hay, y varios.

tanuquillo
15/07/2010, 18:11
pero a que bit rate? a 128?
yo habia oido algo de 8 kbps
digo un mp3 de los que te bajas a pelo de internet y meterlo y que suene.
siempre se habia dicho que era imposible. el moon shell por ejemplo no puede cargarlos

jduranmaster
15/07/2010, 19:15
con el programa que digo yo puedes elegir la tasa de conversión.

tanuquillo
15/07/2010, 21:19
echare un ojo. y con el otro que me quede mirare a ver si veo la rom

saucjedi
16/07/2010, 08:25
pero a que bit rate? a 128?
yo habia oido algo de 8 kbps
digo un mp3 de los que te bajas a pelo de internet y meterlo y que suene.
siempre se habia dicho que era imposible. el moon shell por ejemplo no puede cargarlos

A 128 seguro, pero creo que lo que dice jdranmaster te generará una rom con el (o los mp3) y el player y ya está. Eso es importante, que a veces parece que la gente no se de cuenta de que el moonshell es software que se está ejecutando y ocupando memoria luego... menos para el MP3 y su player.

jduranmaster
16/07/2010, 12:06
es correcto lo que dices. la aplicación te genera una rom .gba con el player y las pistas de mp3 que hayas seleccionado. asi cuando la arrancas te aparece el player con una pantalla de selección de la pista de musica que quieres escuchar.

tanuquillo
17/07/2010, 02:00
wow no me lo creo. tengo mp3 en la gba sin necesita el mp3 gba player que me compre 2 para la micro.
hexcelente haporte te pazaste

tSuKiYoMi
17/07/2010, 12:06
yo he probado en flashcart para GBA y las roms generadas con el GBA WalkMan funcionan, eso si no he probado a meter mas de 6 canciones para que la rom no sea excesivamente grande.

jduranmaster
17/07/2010, 12:27
aun tengo que probar la nueva versión de la herramienta cuyos enlaces dejo Allen_S por estos lugares. aunque lo mismo el funcionamiento es similar.

GameMaster
17/07/2010, 12:37
Queremos más demos chicos, más demos :)

jduranmaster
17/07/2010, 12:43
estamos en ello. pero tmb de vacaciones......juas.:D

Allen_S
18/07/2010, 01:44
Pues que disfruten sus vacaciones... jajaja.
Estuve leyendo los comentarios... y debo decir:
Cierto... muy cierto, los enlaces los proporcioné yo... déjenme decirles que el GBAlpha Walkman inicialmente se lanzó como una aplicación de pago, si se fijan en la versión 2.0 no se puede hacer "na" no genera ninguna cancion, y tiene muchas mas opciones que la versión previa.
Que puedo comentar de la versión 1.0 ??... pues para empezar decirles que ES EL MEJOR CONVERTIDOR de MP3 a GBA, ya que existían opciones como el GSM Player, Music Player Advance, y hasta el Movie Player, pero seámos sinceros... esas aplicaciones están dirigidas para determinado cartucho... el GBAlpha Walkman es universal.
Leí algun comentario que decía que se podian agregar multitud de pistas, lo que me parece raro porque en la versión 1.0 se puede meter solo 2 unicos archivos de audio (sin importar el peso) aunque para ser sincero estuve a punto de publicar el tutorial de esta aplicación en los foros pertinentes, pèro no me sentí conforme con la versión 2.0... si acaso la versión 1.0 cumple su cometido, porque hay que decirlo... un aplicación que convierta RAPIDO Y SIN PROBLEMAS un archivo mp3 a gba para luego copiar y pegar la cancion en CUALQUIER FLASHCART, eso me parece genial... y no se si ya lo notaron pero se pueden colocar las portadas de los discos por cada canción.
Creo que ya es hora de publicar el tutorial de esta aplicación... estoy viendo en que foro vendría mejor ponerlo... alguna sugerencia??? (Gp32Spain denlo por hecho).

jduranmaster
18/07/2010, 15:18
genial pues cuando te animes sube el tutorial en un post dentro de este hilo. saludos.:awesome:

^OMAP-Cranck^
25/07/2010, 18:46
alguien sabe de donde puedo descarga algun pdf con las especificaciones tecnicas de la GameBoy. y algun tutorial del GBDK?. gracias.

jduranmaster
04/08/2010, 19:36
alguien sabe de donde puedo descarga algun pdf con las especificaciones tecnicas de la GameBoy. y algun tutorial del GBDK?. gracias.

en el developers de GameBoy seguro que tiene que haber algun buen tutorial del GBDK. de todas formas como ya se me acabaron las vacaciones y mañana vuelvo a entrar en acción lo buscare a ver si veo alguno bueno y dejo los enlace por estos lugares.

jduranmaster
07/08/2010, 14:31
hola a todos. tengo una preguntilla que hacer. resulta que he encontrado en el gbadev un codigo fuente que permite una vez generada la rom correpondiente y ejectuda via flashcart en la GBA generar en la tarjeta SD de turno un ficherito con la bios de la GBA. sería desde un pto de vista legal subir a la página dicha rom, o solo podría comentar el código.

saludos.

jduranmaster
07/08/2010, 20:16
bueno mientras espero a que alguien pueda contestarme a la pregunta anterior, aqui os dejo una demo que he sacado del AGB Devlopment Kit. [gracias a manirea por pasarme los links]. Este es uno de los KITs oficiales de Nintendo para programar en la GBA. El ejemplo muestra una demo de un Yoshi con una melodia de fondo. Da la sensación de que se pueden desarrollar grandes demos con el kit.

os dejo unas capturqas y la rom por si la quereis probar en el VisualBoy Advance. Yo aun no he podido probarla en el FlashCart, asi que si alguien se anima, ya sabe.

saludos.:awesome:

saucjedi
07/08/2010, 20:50
hola a todos. tengo una preguntilla que hacer. resulta que he encontrado en el gbadev un codigo fuente que permite una vez generada la rom correpondiente y ejectuda via flashcart en la GBA generar en la tarjeta SD de turno un ficherito con la bios de la GBA. sería desde un pto de vista legal subir a la página dicha rom, o solo podría comentar el código.

saludos.

Subir la BIOS de la GBA a cualquier sitio es ilegal pero distribuir un programa que la copie a SD no porque tú tienes derecho a hacerte un backup de la BIOS de tu máquina.

jduranmaster
07/08/2010, 20:56
Subir la BIOS de la GBA a cualquier sitio es ilegal pero distribuir un programa que la copie a SD no porque tú tienes derecho a hacerte un backup de la BIOS de tu máquina.

ok, gracias saucjedi. en breve subire el codigo para compartilo con todos.

saludos.:awesome:

tanuquillo
08/08/2010, 08:48
a lo mejor es una locura pero hay 3d para la gb clasica?

cualquier cosa simple.

jduranmaster
08/08/2010, 11:32
a lo mejor es una locura pero hay 3d para la gb clasica?

cualquier cosa simple.

pues no sabria decirte, la verdad es que de los ejemplos y codigos fuente que yo conozco no he visto nada al respecto.

Segata Sanshiro
08/08/2010, 11:54
a lo mejor es una locura pero hay 3d para la gb clasica?

cualquier cosa simple.

Hay un Stunt Race casero (aunque solo era una demo no jugable) en 3D, pero no sé si era en tiempo real o si usaba alguna otra técnica. Pero demos técnicas 3D las hay hasta en Commodore 64 y anteriores, algo tiene que haber en GB.

jduranmaster
08/08/2010, 11:56
si hay algo hecho seguro que lo puedes encontrar en el GBDEV.

jduranmaster
08/08/2010, 13:37
bueno pues aqui os dejo el codigo fuente que se necesita para dumpear la bios de la GBA. huelga decir que distribuir el fichero con la bios que se genera uanvez terminado el proceso es ilegal, asi que mucho ojo con lo que haceis gañanes. Aqui os pongo el código fuente, y me gustaria agradecer a "SteppenWolf" uno de los habituales del GBAdev su cordial ayuda y explicaciones al respecto. Yo he compilado el codigo fuente que os paso usando el devkitPRO, aunque inicialmente se trataba de un proyecto desarrollado con el devkitADV. en cualquier caso funciona correctamente.




//-------------------------------------------------------------------------------
// Esta es una adaptación del codigo que se encuentra en descarga en el sitio web
// www.gbadev.org.
// autor: jduranmaster
// version: 1.0
// comentarios: gracias a SteppenWolf por los tutos.
//-------------------------------------------------------------------------------


#include <gba.h>
#include <fat.h>
#include <stdio.h>
#include <stdlib.h>


// el bucle de siempre.!!!!!!
//---------------------------------------------------------------------------------
void waitForever() {
//---------------------------------------------------------------------------------
while (1)
VBlankIntrWait();
}

//---------------------------------------------------------------------------------
// PROGRAMA PRINCIPAL
//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------


irqInit();
irqEnable(IRQ_VBLANK);

consoleDemoInit();

iprintf("GBA Bios Dumper\n\n");

if (fatInitDefault()) {
iprintf("Sistema de ficheros FAT inicializado\n");
} else {
iprintf("Fallo de inicializacion del sistema de ficheros FAT\n");
waitForever();
}

u32 *bios = (u32 *)malloc(0x4000);

if ( bios ) {
iprintf("Memoria Asignada\n");
} else {
iprintf("Fallo en la asignacion de Memoria\n");
waitForever();
}

int i;

for (i=0; i<0x4000; i+=4)
{
// la llamada MidiKey2Freq de la bios nos permite leer
// de la bios los bits de menor peso. Para mejorar la
// precisión leemos 4 veces
u32 a = MidiKey2Freq((WaveData *)(i-4), 180-12, 0) * 2;
u32 b = MidiKey2Freq((WaveData *)(i-3), 180-12, 0) * 2;
u32 c = MidiKey2Freq((WaveData *)(i-2), 180-12, 0) * 2;
u32 d = MidiKey2Freq((WaveData *)(i-1), 180-12, 0) * 2;

// y finalmente recosntruimos la palabra de 32 bits
// que nos interesa a aprtir de las 4 palabras leidas
// durante el proceso llevado a cabo anterioremente.
u32 abcd = ( a & 0xff000000 ) |
( d & 0xff000000 ) >> 8 |
( c & 0xff000000 ) >> 16 |
( b & 0xff000000 ) >> 24;
bios[i/4] = abcd;

//escribimos un punto cada 256 bytes.
if ( (i & 0xff) == 0 ) iprintf(".");

}

iprintf("\nBios dumped, salvando fichero\n");

FILE *biosFile = fopen("biosgba.bin","wb");
if (biosFile ) {
fwrite(bios,16384,1,biosFile);
fclose(biosFile);
iprintf("bios guardada en fichero!");
} else {
iprintf("fallo en la creacion del fichero de la bios");
}

waitForever();

return 0;
}



tmb os dejo unas capturas que he realizado con el VisualBoy Advance. Una cosa que debeis tener encuenta es que el programa comprueba primero que el sistema de ficheros es FAT asi que si no teneis vuestras SD formateadas con ese sistema de ficheros olvidaos de que funcione, porque todo el código esta basado en esa premisa. yo lo he probado con el VisualBoy Advance y logicamente ahi no funciona pero usandolo en la FlashCArt de la GBA ha tirado y ha generado el fichero con la bios grabada. Saludos.:awesome:

jduranmaster
08/08/2010, 13:43
Aqui os dejo otra de las demos de ejemplo que se realizaron con el AGB Devleopment Kit. en este caso se trata de un minijuego en el que controlamos a un delfin y podemos moverlo por la pantalla para saltar obstaculos y demas. Una cosa que me ha gustado mucho de este kit de desarrollo es que al ser el oficial de Nintendo incorpora toda la documentación oficial de la GBA y vienen muchos tutoriales para probar cosas. Sobre todo me ha sorprendido el tutorial dedicado al apartado gráfico. PRoximamente mas. SALUDOS.:awesome:

GameMaster
10/08/2010, 11:21
Thanks bro.

jduranmaster
10/08/2010, 19:42
Thanks bro.

no hay de que socio. aun sigues de vaciones?, que las disfrutes.:awesome:

GameMaster
12/08/2010, 16:02
Yep, espero que la semana que viene cuando vuelva por aqui esto este repleto de mas demos :brindis:

xzakox
12/08/2010, 16:58
Yo tengo pendiente hacer la parte de sonido del tutorial, que es larga, pero ahora mismo bufff, creo que va esperar a después del verano. :-)

jduranmaster
12/08/2010, 19:34
Yo tengo pendiente hacer la parte de sonido del tutorial, que es larga, pero ahora mismo bufff, creo que va esperar a después del verano. :-)

sin prisa joer, solo faltaria que fuesemos pidiendo como cosacos.

^OMAP-Cranck^
14/08/2010, 16:04
espero sacar algun ejemplo yo también en los proximos dias. que pena que se hayan acabado las vacaciones.

tanuquillo
17/08/2010, 11:06
molaria un loquendo para gba.
metes un txt y tienes audio libros por un tubo

jduranmaster
17/08/2010, 21:40
joer como pides!!!!!!!!

tanuquillo
17/08/2010, 23:43
pero uno de esos cutres con voz de pena. no tan buena como el loquendo.