Registrarse

[ASM] FR | Mostrar Imágenes a Pantalla Completa

CompuMax

Discord: CompuMax#0425
Miembro insignia

[ASM] Mostrar Imágenes a Pantalla Completa


A continuación aprenderemos como mostrar imágenes a pantalla completa (240x160) por medio de ASM en Fire Red y Rojo Fuego.

Las características de la rutina son:

- BG en Modo 0, por lo que se puede seguir haciendo uso de los demás BG y OBJ
- Uso del BG0 para mostrar la imágen
- Tamaño de la imágen de 1x1 hasta 240x160 (pantalla completa)
- Tabla con estructura [Imágen][RAW][Paleta]
- Uso de variable para controlar el índice de la Tabla
- Imágen y RAW comprimidas en LZ77 para ahorrar espacio
- Paleta de 16 colores
- Borrar la imágen de forma segura con la misma rutina sin necesidad de refrescar la pantalla
- O borrar mediante otra rutina (RECOMENDADO)

Herramientas a usar:

- GraphicsGale DESCARGAR
- Nameless Tilemap Editor (NTME) DESCARGAR
- Sphere DESCARGAR
- Compilador THUMB ASM DESCARGAR
- HxD DESCARGAR
- GBA Graphics Editor DESCARGA

Ya con todo a la mano podemos empezar :D

Primero busquemos la imágen que deseamos mostrar, máximo de 240x160 e indexada a 16 colores incluido el primer color que es usado como transparencia. Si tienes problema con ello, pásate por este post donde explico como redimensionar e indexar.

Yo usaré esta:


Ahora abrimos GraphicsGale y creamos un nuevo documento (Ctrl+N) de 256x160 a 4bits


Luego con GraphicsGale también abrimos nuestra imágen, la seleccionamos toda (Ctrl+A) y la copiamos (Ctrl+C). Ahora volvemos al lienzo creado anteriormente (la imágen de 256x160) e importamos la paleta de la siguiente manera:

Presionando la flecha hacia abajo que aparece debajo de la paleta de colores y seleccionando "Load Palette..."


Seleccionamos la opción File > Import From Clipboard para copiar la paleta de la imágen en el portapapeles. Seleccionamos All y OK.


Ahora pintamos toda la imágen con el color de transparencia, para ello seleccionamos el primer color y rellenamos con la herramienta Flood Fill . Luego vayan a las propiedades de la capa y selecciones el color de transparencia de la siguiente manera:


Esto se hace para que no se eliminen colores de la imágen al importar la que vamos a usar. Tambien basta simplemente con deseleccionar la opción de color de transparencia o Transparent Color. Ahora pegamos nuestra imágen y guardamos la imágen en formato PNG o BMP preferiblemente, nos debería quedar así:


Ahora abrimos el Editor de Sphere y seleccionamos importar imágen a mapa, seleccionamos la imágen y en la ventana Tile Dimensions colocamos 8 tanto en el alto como el ancho.




Presionamos OK y luego Sí para eliminar los tiles repetidos y finalmente aceptar.

Ahora abrimos el archivo recien creado por Sphere con la opcion File > Open > Map...


Hacemos una captura de pantalla y vamos a Pain, la pegamos y recortamos la imágen correspondiente al Tileset teniendo cuidado de no recortar pixeles del Tileset para ello pueden hacer uso del zoom, tengan en cuenta que las dimensiones deben de ser en múltiplos de 8px, el cual, es la base de cada Tile tanto horizontal como verticalmente. Una vez recortada la imágen correctamente, guardamos como imágen como Mapa de bits de 24bits y ya tendremos nuestro Tileset.

Ahora lo abrimos con GraphicsGale y reducimos la profundidad de color con la opción All Frames > Color Depth... y en Pixel Format seleccionamos 4bpp (16 Colors), presionamos OK y ya estárá indexada a 16 colores. Posiblemente el color de transparencia no quede en el primer lugar, para corregirlo sin usar CMP simplemente selecciona toda la imágen (Ctrl+A), córtala (Ctrl+X), haz clic y mantén presionado en el color de transparencia y arrástralo al primer lugar, luego pega la imágen (Ctrl+V) y ya tendrás el color de transparencia donde debería ir :D


Ya estando indexada correctamente la imágen nos queda un ultimo paso para tenminar con el Tileset, éste es colocar el Tile de tranparencia en la primera posición (créeme nos ahorrará muchos dolores de cabeza). Para ello activa la función de transparencia en la capa como vimos anteriormente y selecciona el primer color, ahora haz un zoom con el que puedas trabajar tranquilamente, luego haz clic en la opción Custom Grid y selecciona 8x8. Si no la trae por defecto puedes fácilmente ir a Custom Grid > Setup... > Add y añadirla.


Ahora corta el primer Tile y pégalo donde está el Tile relleno con el color de transparencia, si seleccionaste correctamente y tildaste la opción de transparencia el primer Tile debería quedar con el primer color. Quedándo de ésta manera:


Guardamos la imágen y tendremos finalmente el Tileset a insertar. Pasemos a crear el mapa o RAW. Para ello abrimos NTME, abrimos el Tileset con la opción File > Open TileSet y abrimos el TileMap con la opción File > Open TileMap > From Sphere RPM file. Nos quedará así:


Como pueden ver la imágen contine ciertos "errores" y es que el Tileset cargado es diferente al original (recuerden que cambiamos el primer tile por el de transparencia). Para corregirlo solo basta buscar donde debería esta el tile de transparencia y rellenar dichos Tiles, finalmente rellenar los Tiles correspondientes con el Tile de transparencia, para saber donde van los Tiles de Transparencia NTME muestra una línea punteada al final de los 240px horizontales (esa es el área de la imágen que se muestra en pantalla), lo que esté despues de eso va de color transparente como la imágen que deseamos insertar al principio. Si hacemos todo bien nos quedará así:


Ahora vamos a Edit > Extra > Change All Palettes y seleccionamos Palette D [14], guardamos el TileMap y éste será el TileMap de nuestra imágen.

Guardamos la imágen y tendremos finalmente el Tileset a insertar. Pasemos a crear el mapa o RAW. Para ello abrimos NTME, abrimos el Tileset con la opción File > Open TileSet y abrimos el TileMap con la opción File > Open TileMap > From Sphere RPM file. Nos quedará así:


Ahora vamos a Edit > Extra > Change All Palettes y seleccionamos Palette D [14], guardamos el TileMap y éste será el TileMap de nuestra imágen.

Ya teniendo el TileSet (imágen) con su Paleta y el TileMap (RAW), procedemos a insertarla con GBA Graphics Editor. Para ello abrimos GBA Graphics Editor y cargamos nuestra ROM Fire Red o Rojo Fuego y abrimos la ventana Image Control (Ctrl+I) en la pestaña Windows. Por defecto debería cargar una imágen comprimida por lo que no debemos hacer más nada que hacer clic en Import a bitmap, hacemos clic en Browse... y buscamos nuestro TileSet. Ahora en la sección Palette en Palette offset colocamos un offset con suficiente espacio vacío. Para ello podemos usar HxD para confirmar, por ser una ROM limpia usaré 0x800000 luego en la sección Graphics en Graphics offset colocamos el offset de la paleta más 0x20, es decir, 0x800020, ya que una paleta de 16 colores sin comprimir ocupa 0x20 tambien puedes insertar tanto la paleta como la imágen donde desees, lo importante es tener suficiente espacio para los datos nuevos y apuntar los offset para la Tabla. Finalmente deja el resto de las opciones como aparece la imágen para que no repuntee la imágen que usamos como referencia y que aborde la instrucción si no hay suficiente espacio disponible para insertar la imágen (así no dañaremos la ROM).


Presionamos OK y Finished. luego guardamos y abrimos la ROM con HxD vamos al offset donde insertamos la paleta 0x800000 en nuestro caso y buscamos (Ctrl+F) la secuencia FFFFFFFF a partir de ese offset, es decir, seleccionando la opción Adelante y verificamos que tengamos suficiente espacio libre. Yo ya lo he hecho y he encontrado el offset 0x800F50.


Volvemos a GraphicsGale y en la vetana Image Control hacemos clic en Load raw seleccionamos All files en los tipos de archivos y seleccionamos la RAW de nuestra imágen.


Presionamos OK y salvamos (Ctrl+S) y ya tendremos insertada nuestro TileMap. Ahora volvemos a HxD y volvemos a buscar espacio libre buscando la secuencia FFFFFFFF. He conseguido el offset 0x8012E8. Ten en cuenta que todos los archivos que insertemos en la ROM deben estar alineados en pasos de 4 bytes por lo que deben terminar en 0, 4, 8 o C para que no tengan problemas con la rutina THUMB, como el offset encontrado termina en 8 lo podemos usar de forma segura. Volvemos a GraphicsGale e insertamos el otro TileMap (la de borrar) en la dirección encontrada 8012E8. Ya tendremos lo necesario para armar nuestra Tabla y hacer funcionar nuestra rutina.

Buscamos nuevamente espacio disponible en nuestra ROM. Yo he conseguido el offset 0x801388 pero por razones de comodidad usaré el offset 0x801390. Para armar la tabla sólo debemos permutar los offsets donde insertamos la(s) imágen(es), la(s) paleta(s) y las RAW, recuerden que pueden insertar tantas imágenes deseen hasta un total de 255 más la de borrar. Simplemente asegúrense de que en los TileSet el primer Tile siempre sea el transparente, así no deberán insertar una raw para borrar cada imágen independientemente sino que la primera no servirá para borrarlas todas ¿Ya me entendíste cierto?. Ok permutando los offsets tenemos:

TileSet : 0x08800020 => 20 00 80 08
TileMap Imagen: 0x08800F50 => 50 0F 80 08
Paleta : 0x08800000 => 00 00 80 08
TileMap Borrar : 0x088012E8 => E8 12 80 08

Luego nuestra tabla tentrá la estructura [TileSet][TileMap][Paleta], es decir, [20 00 80 08][50 0F 80 08][00 00 80 08]. Por cuestión de orden en la tabla colocaré primero los datos de borrar y luego el de las imágenes (en mi caso la imágen) quedando de esta manera:

[20 00 80 08][E8 12 80 08][00 00 80 08][20 00 80 08][50 0F 80 08][00 00 80 08]

Una vez llenada la tabla procedemos a editar y compilar la rutina que Cargará las imágenes:

Código:
.thumb
.align 2

    push {r4,lr}        @;Almacena el registro no dinámico y el registro de enlace

Valores_Iniciales:
    ldr r0, =0x000040F2     @;Carga el offset de variable 0x40F2 la variable puede ir de 0x00 hasta 0xFF para un total de 256 imagenes
    ldr r4, =(0x0806E454+1) @;Carga el offset de la rutina que la desencripta (el +1 indica que la rutina está en modo THUMB)
    bl Ejecuta        @;Y la manda a ejecutar, ésta devuelve en R0 el valor de la variable
    ldrb r0, [r0]        @;Carga el primer byte del Registro R0 (valor de la variable) en R0
    ldr r2, TABLA        @;Carga el offset de la Tabla
    mov r3, #0xC        @;Impone R3 como constante y le da el valor de 0xC (longitud de datos por entrada de la Tabla)
    mul r3, r0        @;Multiplica el valor de la variable por 0xC para obtener el numero de entrada de la Tabla
    add r3, r2, r3        @;Suma el offset de la Tabla al numero de entrada (multiplo de 0xC) para ir al indice de la entrada

Carga_Paleta:
    mov r4, #0x8        @;Carga en R4 0x8
    add r2, r3, r4        @;Desplaza el puntero 8 bytes para cargar la Paleta
    ldr r0, [r2]        @;Fuente: Puntero de la Paleta de la entrada de la Tabla
    ldr r1, PAL        @;Destino: Paleta (0xD)
    mov r2, #0x10        @;Longitud/2: Paleta de 16 colores = 0x20 /2 = 0x10(Modo 16bits o THUMB)
    swi 0xb            @;Copia directamente a la memoria especificada en R1, lo que está en R0 con una longitud de 2*R2

Carga_Tile:
    ldr r0, [r3]        @;Fuente: Puntero del Tileset en la entrada de la Tabla
    ldr r1, Char_Base     @;Destino: 1er Tile BG0
    swi 0x12        @;Descomprime el Tile que está en LZ77 de la fuente R0 al destino R1
    push {r0-r3}        @;Almacena los registros que se están usando
    swi 0x5            @;VBlankIntrWait = Espera a que haya una interrupción por blanqueo vertical   

Carga_RAW:
    pop {r0-r3}        @;Recupera los registros que se están usando
    add r2, r3, #0x4    @;Desplazo el puntero 4 bytes para cargar la RAW
    ldr r0, [r2]        @;Fuente: Puntero de la RAW en la entrada de la Tabla
    ldr r1, Map_Base    @;Destino: 1er Mapa BG0
    swi 0x12        @;Descomprime el Mapa que está en LZ77 de la fuente R0 al destino R1
    pop {r4,pc}        @;Carga el puntero a la instrucción siguiente al llamar la sub-rutina
   
Ejecuta:
    bx r4            @;Ejecuta la rutina que se encuentra en el offset almacenado en R4

Map_Base:    .word 0x0600F800    @;Offset donde empieza el Map Base del BG0
Char_Base:    .word 0x06008000    @;Offset donde empieza el Tile Base del BG0
TABLA:      .word 0x08B00000    @;Offset de la Tabla
PAL:        .word 0x020375F8+(0x20*0xD) @;Slot de Paleta, en este caso 0xD
- En la línea ldr r0, =0x000040F2 colocamos la variable que deseemos usar
- En la línea ldr r4, =0x0806E455 colocamos el offset correspondiente a la rutina que desencripta las variables, 0x0806E454 = Fire Red o 0x0806E48C = Rojo Fuego se le agrega +1 para indicar al procesador que es una rutina THUMB
- En la línea TABLA: .word 0x08801390 colocamos el offset de la tabla
- En la línea PAL: .word 0x020375F8 + (0x20 * 0xD) reemplazamos 0xD por el slot de la paleta a usar. Recomiendo usar con total seguridad las paletas 0xD, 0xE y 0xF ya que corresponden a los textox y textbox y éstas se actualizan con sus valores originales cuando se llama cualquier diálogo o menú.

Para borrar la imágen tenemos 3 opciones:

1) Si hiciste el paso opcional con todas las imágenes, algo que daría un poco de pereza si se van a insertar muchas imágenes :)

En este caso se asume que el primer Tile está completamente relleno del color transparente, por lo que al rellenar toda la RAW con 00 00 le estamos indicando que rellene la pantalla con el Tile 0 (el primero) con la Paleta 0 y la imágen mostrada será completamente transparente. Para ello compilamos la siguiente rutina:

Código:
/*NOTA: Como la Map-Base va desde 0x0600F800 hasta 0x06010000 tiene una longitud de 0x800
y como cada vez que se ejecuta un STMIA R0!, {R1-R4} escribe en la Map-Base 16 bytes o 0x10 bytes
(4 bytes x 4 registros), entonces se debe hacer esa operación 80 veces (0x80 x 0x10 = 800) */

.thumb
.align 2

    push {r4-r5,lr}        @;Almacena en la pila el registro de enlace

    ldr r0,Map_Base        @;Destino: Map_Base
    mov r1,#0        @;Fuente: Carga 0x00000000 en R1
    mov r2,#0        @;Fuente: Carga 0x00000000 en R2
    mov r3,#0        @;Fuente: Carga 0x00000000 en R3
    mov r4,#0        @;Fuente: Carga 0x00000000 en R4
    mov r5,#0        @;Reinicia R5 opara usarlo como contador

Borrar_Mapa:   
    stmia r0!, {r1-r4}    @;Almacena el contenido de los registros R1-R4 a partir de la dirección especificada en R0,
                @;incrementando las direcciones para cada palabra y escribe el valor actualizado de R0.
    add r5,r5,#1        @;Aumenta el contador en 1
    cmp r5,#0x80        @;Compara si se realizó la operación 0x80 veces
    bne Borrar_Mapa        @;Si no se culpe la comparación Sigue borrando el TileMap, si se cumple continúa a Fin y termina la rutina.

Fin:
    pop {r4-r5,pc}        @;Carga el puntero a la instrucción siguiente al llamar la sub-rutina

Map_Base:    .word 0x0600F800 @;Offset donde empieza el Map Base del BG0
2) Si omitiste el paso opcional

En este caso como el primer Tile NO está completamente relleno del color transparente debemos borrar al menos el primer Tile a parte de borrar la RAW para que quede de la misma forma que la opción anterior. Para ello compilamos la siguiente rutina:

Código:
/*NOTA: Como la Map-Base va desde 0x0600F800 hasta 0x06010000 tiene una longitud de 0x800
y como cada vez que se ejecuta un STMIA R0!, {R1-R4} escribe en la Map-Base 16 bytes o 0x10 bytes
(4 bytes x 4 registros), entonces se debe hacer esa operación 80 veces (0x80 x 0x10 = 800) */

/*NOTA2: Como cada tile tiene una longitud de 0x20 y como cada vez que se ejecuta un STMIA R0!, {R1-R4}
escribe en la Char-Base 16 bytes o 0x10 bytes (4 bytes x 4 registros), entonces para borrar el primer Tile
se debe hacer esa operación 2 veces (0x2 x 0x10 = 20) */

.thumb
.align 2

    push {r4-r6,lr}        @;Almacena en la pila el registro de enlace

    ldr r0,Map_Base        @;Destino: Map_Base
    mov r1,#0        @;Fuente: Carga 0x00000000 en R1
    mov r2,#0        @;Fuente: Carga 0x00000000 en R2
    mov r3,#0        @;Fuente: Carga 0x00000000 en R3
    mov r4,#0        @;Fuente: Carga 0x00000000 en R4
    mov r5,#0        @;Reinicia R5 para usarlo como contador
    mov r6,#0        @;Reinicia R6 para usarlo como contador

Borrar_Mapa:   
    stmia r0!, {r1-r4}    @;Almacena el contenido de los registros R1-R4 a partir de la dirección especificada en R0,
                @;incrementando las direcciones para cada palabra y escribe el valor actualizado de R0
    add r5,r5,#1        @;Aumenta el contador en 1
    cmp r5,#0x80        @;Compara si se realizó la operación 0x80 veces
    bne Borrar_Mapa        @;Si no se culpe la comparación Sigue borrando el TileMap, si se cumple continúa para borrar el TileSet
    mov r5,#0        @;Reinicia R5 para usarlo como contador
    ldr r0,Char_Base    @;Destino: Char_Base

Borrar_Tile:
    stmia r0!, {r1-r4}    @;Almacena el contenido de los registros R1-R4 a partir de la dirección especificada en R0,
                @;incrementando las direcciones para cada palabra y escribe el valor actualizado de R0
    add r5,r5,#1        @;Aumenta el contador en 1
    cmp r5,#0x2        @;Compara si se realizó la operación 0x2 veces
    beq Fin            @;Si se culpe la comparación va a Fin y termina la sub-rutina
    b Borrar_Tile        @;Si no sigue borrando el TileSet

Fin:
    pop {r4-r6,pc}        @;Carga el puntero a la instrucción siguiente al llamar la sub-rutina

Map_Base:    .word 0x0600F800 @;Offset donde empieza el Map Base del BG0
Char_Base:    .word 0x06008000 @;Offset donde empieza el Tile Base del BG0
3) Si omitiste el paso opcional

Igual que en el caso anterior que el primer Tile NO está completamente relleno del color transparente debemos borrar el primer Tile a parte de borrar la RAW pero si queremos hacer un borrado más seguro, borramos completamente la RAW y el TileSet. Para ello compilamos la siguiente rutina:

Código:
/*NOTA: Como la Map-Base va desde 0x0600F800 hasta 0x06010000 tiene una longitud de 0x800
y como cada vez que se ejecuta un STMIA R0!, {R1-R4} escribe en la Map-Base 16 bytes o 0x10 bytes
(4 bytes x 4 registros), entonces se debe hacer esa operación 80 veces (0x80 x 0x10 = 800) */

/*NOTA2: Como la Char-Base de BG0 va desde 0x06008000 hasta 0x060E0000 tiene una longitud de 0x6000
y como cada vez que se ejecuta un STMIA R0!, {R1-R4} escribe en la Char-Base 16 bytes o 0x10 bytes
(4 bytes x 4 registros), entonces se debe hacer esa operación 600 veces (0x600 x 0x10 = 6000) */

.thumb
.align 2

    push {r4-r6,lr}        @;Almacena en la pila el registro de enlace

    ldr r0,Map_Base        @;Destino: Map_Base
    mov r1,#0        @;Fuente: Carga 0x00000000 en R1
    mov r2,#0        @;Fuente: Carga 0x00000000 en R2
    mov r3,#0        @;Fuente: Carga 0x00000000 en R3
    mov r4,#0        @;Fuente: Carga 0x00000000 en R4
    mov r5,#0        @;Reinicia R5 para usarlo como contador
    mov r6,#0        @;Reinicia R6 para usarlo como contador

Borrar_Mapa:   
    stmia r0!, {r1-r4}    @;Almacena el contenido de los registros R1-R4 a partir de la dirección especificada en R0,
                @;incrementando las direcciones para cada palabra y escribe el valor actualizado de R0
    add r5,r5,#1        @;Aumenta el contador en 1
    cmp r5,#0x80        @;Compara si se realizó la operación 0x80 veces
    bne Borrar_Mapa        @;Si no se culpe la comparación Sigue borrando el TileMap, si se cumple continúa para borrar el TileSet
    mov r5,#0        @;Reinicia R5 para usarlo como contador
    ldr r0,Char_Base    @;Destino: Char_Base

Borrar_Tile:
    stmia r0!, {r1-r4}    @;Almacena el contenido de los registros R1-R4 a partir de la dirección especificada en R0,
                @;incrementando las direcciones para cada palabra y escribe el valor actualizado de R0
    add r5,r5,#1        @;Aumenta el contador en 1
    cmp r5,#0x60        @;Compara si se realizó la operación 0x80 veces
    beq Ciclo        @;Si se culpe la comparación va a Ciclo y verifica si ya se borró todo el TileSet
    b Borrar_Tile        @;Si no sigue borrando el TileSet

Ciclo:
    add r6,r6,#1        @;Aumenta el contador en 1
    cmp r6,#0x10        @;Compara si se realizó la operación 0x10 veces para un total de 0x600 veces
    beq Fin            @;Si se culpe la comparación va a Fin y termina la sub-rutina
    mov r5,#0        @;Sino reinicia en contador R5
    b Borrar_Tile        @;Y continúa borrando el TileSet

Fin:
    nop            @;NOP (No Opera) función que no hace nada excepto gastar un comando
                @;se usa para alinear el código a comandos pares y pueda compilarse la sub-rutina
    pop {r4-r6,pc}        @;Carga el puntero a la instrucción siguiente al llamar la sub-rutina

Map_Base:    .word 0x0600F800 @;Offset donde empieza el Map Base del BG0
Char_Base:    .word 0x06008000 @;Offset donde empieza el Tile Base del BG0
Ahora descomprimimos el compilador THUMB y arrastramos la rutina ASM sobre el Archivo por lotes thumb. Si no contiene errores la rutina, creará un archivo binario con el mismo nombre que le hayamos dado a la rutina, hacemos lo mismo con la rutina de Borrar que mejor se adapte a nuestro trabajo y ¡listo!. Ya tenemos nuestras rutinas compliadas en hexadecimal.

Ahora abrimos los archivo .bin generado por el compilador con HxD, copiamos el código hexadecimal y buscamos nuevamente espacio libre en la ROM teniendo en cuenat que deben estar alineados a 4 bytes por lo que el offset debe terminar en 0, 4, 8 o C. Pegamos, guardamos y listo! ya hemos insertado correctamente nuestras rutinas.

Ahora sólo basta abrir la ROM con AdvanceMap y editar algún script para ejecutar la rutina. Recuerda que por ser en modo THUMB el offset de la rutina a llamar debe ser el offset donde se insertó +1, es decir, ejemplo s1 insertó en 0x800000, entonces para llamar la rutina lo hacemos con un callasm 0x800001

Aquí un ejemplo del script:

Código:
'---------------
#dynamic 0x900000
#org @Inicio
setvar 0x40F2 0x0  'selecciona la primera entrada de la tabla.
callasm 0x801391   'llama la rutina que Carga la imágen 0x801390+1
pause 0x50         'hace un pausa para visualizar la imágen
callasm 0x801421   'llama la rutina que Borra la imágen 0x801420+1
end                'fin del script
Y aquí el resultado final en Fire Red y Rojo Fuego respectivamente:



PD: Es mi primera rutina ASM y quizás estoy usando comandos de más o nombrando mal los términos, así que si alguién tiene alguna corrección me puede escribir por el perfil o por privado y lo corregiré a la brevedad.

Saludos!

Max.


 
Última edición por un moderador:
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Primer comentario? :)

Voy directo al grano,un tutorial bien redactado y con imagenes para reforzar
la comprensión de este mismo,muy completo y util (Al menos para mi).
En resumen,el tutorial esta exelente,facil de comprender y hasta de aplicar
me atreveria a decir,gracias por aportar,eres bueno en RH (Mucho mas que yo :I)

Ah y tengo una duda (Obvia),puedo meter mas de una imagen o no?
 

KevinXDE

Usuario mítico
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Menudo tutorial te has marcado macho! Esto es de las cosas más útiles que he visto por ahí xD. encima todo muy bien explicado y con imágenes.

Seguro que haré uso de la rutina! Gracias :v
 

Kaiser de Emperana

Called in hand
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Al final no lo hiciste special xD

Está bueno, es una rutina simple, pero sirve. Alguien seguro que se va a hacer un menú con scripts usando esto :p

Sobre la rutina, hay un par de tonterías que comentar:

.thumb
.align 2

push {r0-r4,lr} @;Almaceno en la pila el valor de los registros a usar y el registro de enlace
ldr r0, =0x000040F2 @;Cargo el offset de variable 0x40F2 la variable puede ir de 0x00 hasta 0xFF para un total de 256 imágenes
ldr r4, =0x0806E455 @;0x0806E48D para Rojo Fuego Cargo el offset de la rutina que la desencripta
bl call_r4 @;Y la mando a ejecutar, ésta devuelve en R0 el valor de la variable

DisplayImg:
ldrb r0, [r0] @;Cargo el primer Byte del Registro R0 (valor de la variable) en R0
ldr r2,TABLA @;Cargo el offset de la Tabla
mov r3, #0xC @;Impongo R3 como constante y le doy el valor de 0xC (longitud de datos por entrada de la tabla)
mul r3, r0 @;Multiplico el valor de la variable por 0xC para obtener el numero de entrada de la tabla
add r2, r2, r3 @;Sumo el offset de la tabla al número de entrada (multiplo de 0xC)
ldr r0, [r2] @;Fuente: Puntero del tileset de la entrada
ldr r1,=0x06008000 @;Destino: Caracter base para el BG0
swi 0x12 @;Descomprime el tile en LZ77 de la fuente R0 al destino R1
add r2, r2, #0x4 @;Desplazo el puntero 4bytes para cargar la RAW
ldr r0, [r2] @;Fuente: Puntero de la RAW de la entrada
ldr r1,=0x0600F800 @;Destino: Mapa base para el BG0
swi 0x12 @;Descomprime el Mapa en LZ77 de la fuente R0 al destino R1
add r2, r2, #0x4 @;Desplazo el puntero 4bytes más para cargar la Paleta
ldr r0, [r2] @;Fuente: Puntero de la Paleta de la entrada
ldr r1,PAL @;Destino de la Paleta (0xD)
mov r2, #0x10 @;Longitud de la Paleta (16 colores) 20h/2 (Modo 16bits o THUMB)
swi 0xb @;Copio directamente a la memoria especificada en R1, lo que está en R0 con una longitud de R2
b End

End:
pop {r0-r4,pc} @;Cargo los valores originales de los registros usados y el contador de programa
bx lr

call_r4: bx r4

TABLA: .word 0x08801390 @;Offset de la tabla
PAL: .word 0x020375F8 + (0x20 * 0xD) @;Slot de Paleta 0xD
Estas un poco confundido con las etiquetas me parece. Ninguna de las cosas marcadas en rojo son necesarias, específicamente el "b End". No tiene caso ponerlo, porque end es lo que sigue en la rutina, aunque no esté lo ejecutaría igual xD. Las etiquetas que pusiste no es que estén mal, pueden servir para organizar el código, pero no afectan en nada. La única realmente necesaria es el call_r4.

Por otro lado, el "bx lr" está mal por donde se lo mire. Por un lado nunca se va a ejecutar, ya que lo que pinté en azul no lo permite. Lo que estás haciendo es pushear el lr, que tiene un puntero a la instrucción siguiente a donde se llamó a la rutina y al final de la misma lo estás popeando en el pc, que es el puntero a la instrucción siguiente; por lo que el procesador pasa a ejecutar la instrucción siguiente a la que estaba cuando se llamó tu rutina. Por lo que como dije, el bx lr, nunca se ejecutaría.
Y por el otro lado, si se ejecutara ( si hubieras hecho "push {r0-r4} ... pop {r0-r4}"), lo que tendrías sería un bucle infinito. Porque cuando ejecutás el "bl call_r4", estás cambiando el lr de vuelta, por lo que perderías el valor original.
"bx lr" sirve únicamente como return de rutinas que no llaman a ninguna subrutina (o sea, ejecutan un bl).

O sea que básicamente, tu rutina está malgastando 4 valiosos bytes, de los más de 32 millones que tiene el rom. ¡Vergüenza te debería dar! (?
 

Gold

Porrero a tiempo parcial
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Yo ya tenía una rutina que hace exactamente lo mismo a la tuya que usó tambien IK en el Voces Celestiales,solo que por slgún motivo la imágen mo se borraba del todo del BG0, había que hacerle un refresh para que se fuera, no sé si era error mio o de mi Rom, pero quedaba incompleta. Igual gracias por la rutina.
 

Xabier2012

Usuario mítico
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Si haces diálogos estos se superponen a la imagen?
 
M

Miembro eliminado 28262

Invitado
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Aportazo colega!
yo estaba usando el método que mencionó Gold, pero daba algunos errores además deque era medio complicado el método, creo era con el sistema de diplomas o algo así y la cosa quedaba medio cutre xD

Pero OH MI DIOS, se imaginan lo que se puede hacer con esto? Llevo años buscando una forma de hacer esto de forma fácil asi que esto me cae como anillo al dedo..

Ya tengo pensado usarlo en varios sitemas del FinalRed y el Advance..algo como.. una carta que se muestre a pantalla completa, algunas cinematicas estilo Pokewood, algun mapa dentro de una cueva que te diga donde te encuentras exactamente.. (referencias a sistemas de otros hackroms)

En fin, que paso de enrollarme más, se agradece que compartas esto con nosotros, espero más gente sepa darle la utilidad que merece, y que lo hayas hecho tambien para RF lo hace espectacular.

Te daría repu pero esa wea ya no existe :'v
Saludos y Buenas vibras!

#SeichCapriccola
 

Bugrhak

A long time ago I used to call myself "Subzero".
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Hace unas cuantas semanas estaba intentando hacer algo similar a esto para mi hack, pero lo dejé por flojera '^^
Felicidades por tu primera rutina, sin duda la usaré para algo de lo que tengo pensado.
Me alegra ver que la rutina funcione tanto en FR como en RF, eso le da un toque de mas "funcionalidad" a la rutina!

----------​

Estaría bueno que se pudiera elegir en que parte de la pantalla se muestra la imagen en el caso de que esta sea de una dimensión específica y menor a 240x160 ya que si es
de menores dimensiones a las recién mencionadas, la imagen se verá a partir de la esquina superior izquierda, y dependiendo de lo que se quiera mostrar, puede ser algo cutre (o no).

----------​

Gracias por el aporte!
♠Un saludo!♠
 

Adke

weeeh
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Si haces diálogos estos se superponen a la imagen?
Sí, la caja de diálogo va en el bg0, así que se superpondría y podría causar errores.

♦$uᏰz£r∅♦;378800 dijo:
Estaría bueno que se pudiera elegir en que parte de la pantalla se muestra la imagen en el caso de que esta sea de una dimensión específica y menor a 240x160 ya que si es de menores dimensiones a las recién mencionadas, la imagen se verá a partir de la esquina superior izquierda, y dependiendo de lo que se quiera mostrar, puede ser algo cutre (o no).
Eso es tan simple como dejar con color de fondo los pixeles que te sobran, es decir, si quieres que sea de 80x80 y se vea en la esquina superior derecha haces el tilemap dejando el tilemap vacío excepto los 80x80 pixeles que te interesa que se muestre.
Al estar en el bg0 no debería causar ningún bug gráfico con los tiles, pero no se podrá combinar con cajas de diálogo.

-----

Y ya mi duda es si al poner dos tilemaps seguidos en un script funciona bien o causa error?

PD: Un gran aporte, sigue así ;)
 

Bugrhak

A long time ago I used to call myself "Subzero".
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Eso es tan simple como dejar con color de fondo los pixeles que te sobran, es decir, si quieres que sea de 80x80 y se vea en la esquina superior derecha haces el tilemap dejando el tilemap vacío excepto los 80x80 pixeles que te interesa que se muestre.
Eso lo sé, y de hecho no lo he mencionado porque es algo que se da por sentado que es totalmente posible de hacer.

Aunque ahora viendo la rutina, y la idea que da mi comentario, lo que "propuse" tendría un mejor hogar en una rutina que cargue imágenes pero no como tilemaps.

Así que nada xD
 
Última edición:

CompuMax

Discord: CompuMax#0425
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Al final no lo hiciste special xD

Está bueno, es una rutina simple, pero sirve. Alguien seguro que se va a hacer un menú con scripts usando esto :p

Sobre la rutina, hay un par de tonterías que comentar:

Estas un poco confundido con las etiquetas me parece. Ninguna de las cosas marcadas en rojo son necesarias, específicamente el "b End". No tiene caso ponerlo, porque end es lo que sigue en la rutina, aunque no esté lo ejecutaría igual xD. Las etiquetas que pusiste no es que estén mal, pueden servir para organizar el código, pero no afectan en nada. La única realmente necesaria es el call_r4.

Por otro lado, el "bx lr" está mal por donde se lo mire. Por un lado nunca se va a ejecutar, ya que lo que pinté en azul no lo permite. Lo que estás haciendo es pushear el lr, que tiene un puntero a la instrucción siguiente a donde se llamó a la rutina y al final de la misma lo estás popeando en el pc, que es el puntero a la instrucción siguiente; por lo que el procesador pasa a ejecutar la instrucción siguiente a la que estaba cuando se llamó tu rutina. Por lo que como dije, el bx lr, nunca se ejecutaría.
Y por el otro lado, si se ejecutara ( si hubieras hecho "push {r0-r4} ... pop {r0-r4}"), lo que tendrías sería un bucle infinito. Porque cuando ejecutás el "bl call_r4", estás cambiando el lr de vuelta, por lo que perderías el valor original.
"bx lr" sirve únicamente como return de rutinas que no llaman a ninguna subrutina (o sea, ejecutan un bl).

O sea que básicamente, tu rutina está malgastando 4 valiosos bytes, de los más de 32 millones que tiene el rom. ¡Vergüenza te debería dar! (?
jajaja Pienso hacer un tutorial de como implementar el comando SPECIAL, ya me monto en eso ;)

Y pues gracias hermano por toda la ayuda, siempre es bienvenida!. Ya sabía que por ser mi primera rutina tendría algunos "errores" aunque así como está está funcional al 100%. Seguiré documentándome en GBATEK para traerles más rutinas pronto.

Y para la próxima tendré más cuidado de no malgastar ese 0,0000125% de espacio disponible de la ROM :D

Primer comentario? :)

Voy directo al grano,un tutorial bien redactado y con imagenes para reforzar
la comprensión de este mismo,muy completo y util (Al menos para mi).
En resumen,el tutorial esta exelente,facil de comprender y hasta de aplicar
me atreveria a decir,gracias por aportar,eres bueno en RH (Mucho mas que yo :I)

Ah y tengo una duda (Obvia),puedo meter mas de una imagen o no?
Si dispones de una tabla donde puedes meter entradas de la manera [Imagen][RAW][Paleta] creo que es obvia la respuesta a tu pregunta. Además dejo claro que se pueden insertar hasta 255 imágenes más la de borrar. Aunque fácilmente puede expandirse para trabajar con 65535 imágenes más la de borrado, es decir, que la variable tenga 2 bytes de longitud de 0x0000 hasta 0xFFFF.

Saludos y espero haber aclarado tu duda.

Aportazo colega!
yo estaba usando el método que mencionó Gold, pero daba algunos errores además deque era medio complicado el método, creo era con el sistema de diplomas o algo así y la cosa quedaba medio cutre xD

Pero OH MI DIOS, se imaginan lo que se puede hacer con esto? Llevo años buscando una forma de hacer esto de forma fácil asi que esto me cae como anillo al dedo..

Ya tengo pensado usarlo en varios sitemas del FinalRed y el Advance..algo como.. una carta que se muestre a pantalla completa, algunas cinematicas estilo Pokewood, algun mapa dentro de una cueva que te diga donde te encuentras exactamente.. (referencias a sistemas de otros hackroms)

En fin, que paso de enrollarme más, se agradece que compartas esto con nosotros, espero más gente sepa darle la utilidad que merece, y que lo hayas hecho tambien para RF lo hace espectacular.

Te daría repu pero esa wea ya no existe :'v
Saludos y Buenas vibras!

#SeichCapriccola
jajaja

Deberían de darme un premio por sacarle un halago al veterano SAGE.

Y si bro. Yo lo estaba buscando desde que enpecé mi hack porque deseo hacer un sistema de selección de inicial personalizado. Específicamente esto:


USO PRIVADO. NO LA USEN PUTOS! :D

Pero no conseguí nadie que me hiciera la rutina. Incluso intenté adaptar la rutina de Pabel para cargar Vs. Bar pero luego de cargar 5 imágenes consecutivas se cuelga el juego. Me imagino que funciona de otra manera (además de ser más extensa), aún no me pongo a descifrarla.

Sí, la caja de diálogo va en el bg0, así que se superpondría y podría causar errores.


Eso es tan simple como dejar con color de fondo los pixeles que te sobran, es decir, si quieres que sea de 80x80 y se vea en la esquina superior derecha haces el tilemap dejando el tilemap vacío excepto los 80x80 pixeles que te interesa que se muestre.
Al estar en el bg0 no debería causar ningún bug gráfico con los tiles, pero no se podrá combinar con cajas de diálogo.

-----

Y ya mi duda es si al poner dos tilemaps seguidos en un script funciona bien o causa error?

PD: Un gran aporte, sigue así ;)
Como ya le respondiste a Subzero, respondo tu duda ;). Como prueba hice un script donde se alternaba entre 2 imágenes (me dió flojera insertar más) e hice un bucle para que se repitiera unas 50 veces y al final borré y no tuve ningún problema. Si desean puedo explicar lo que hace la rutina. Así se darán cuenta de que no existe error posible :D

Si haces diálogos estos se superponen a la imagen?
No bro. Si llamas la textbox, ésta borra la imágen puesto que hace uso completo de la BG0. Para hacer eso deberíamos trabajar con las otras BG como la BG1, BG2 o BG3 (actualmente estoy trabajando en ello). Pero estas son usadas para cargar los tiles del mapeado, así que para volver al estado original se debería hacer un respaldo de los tiles y sus respectivas RAW antes de modificar algo y luego restaurarlas al terminar de mostrar la imágen o hacer simplemente un WARP de nuevo al mapa. Preferiblemente guardando antes la posición y dirección del OW (algo en lo que pienso trabajar) por si cargamos la imágen en cualquier lugar del mapa, como por ejemplo abrir un mapa del pueblo totalmente distinto al que usa el juego por defecto o un menú personalizado, no sé... lo que te dé la imaginación.

:D

Espero haber aclarado tu duda.
 
Última edición:

Fran Agustín

Si el sol besa tus ojos, ni cuenta te das.
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Buenas Max, me encanta este aporte y, en especial, que te unas a nuestro clan de ASM.

Con respecto a mejorar la rutina:
  1. Cuando llamas al "var decrypter" estás usando el offset original + 1 (por ser THUMB), sin embargo la notación que se acostumbra al cargar este tipo de rutinas (puesta muy de moda en la comunidad inglesa por FBI) es: ldr rX, =(0x08XXXXXX+1) (para tener en cuenta que el offset en realidad es el anterior y que le sumas uno por ser una rutina THUMB a la que vas a llamar). En fin, solo digo que puede ayudarte a ti y a los que lean a no perderlo de vista.
  2. Por supuesto, lo que el jefecito te ha dicho de los branches.
  3. El método que has usado de meter otro tilemap para borrar la imagen ocupa demasiado espacio, es mucho más eficiente hacer un loop que rellene con 00s (por el primer tile del tilemap). Si tienes alguna duda con eso, en otro momento te explico lo que quiero decir.

♦$uᏰz£r∅♦;378800 dijo:
Hace unas cuantas semanas estaba intentando hacer algo similar a esto para mi hack, pero lo dejé por flojera '^^
Felicidades por tu primera rutina, sin duda la usaré para algo de lo que tengo pensado.
Me alegra ver que la rutina funcione tanto en FR como en RF, eso le da un toque de mas "funcionalidad" a la rutina!

----------​

Estaría bueno que se pudiera elegir en que parte de la pantalla se muestra la imagen en el caso de que esta sea de una dimensión específica y menor a 240x160 ya que si es
de menores dimensiones a las recién mencionadas, la imagen se verá a partir de la esquina superior izquierda, y dependiendo de lo que se quiera mostrar, puede ser algo cutre (o no).

----------​

Gracias por el aporte!
♠Un saludo!♠
La posición del background se maneja desde la I/O RAM, por lo que podrías manejarlo con unos cuantos wbtos (aunque si es posible hacerlo con una rutina).

Si haces diálogos estos se superponen a la imagen?
He ahí el punto que más me preocupa: las textboxes usan el BG0. Por lo tanto, al mostrar un mensaje en pantalla lo que debería pasar es que se borre la parte de abajo de la imagen y sea reemplazada por la textbox. En mi opinión sería más útil usar otro BG y recargarlo nuevo si quieres mostrar imágenes y textos.

En fin, saludos y felicitaciones por este gran aporte.

EDIT: @CompuMax olvidé decírtelo ayer, pero no es necesario hacer un push para los registros 0-3, ya que son a lo que llamaríamos "dinámicos". Excepto, claro, en caso de que estés haciendo un hook de otra rutina que no haya terminado de usar esos valores.
 
Última edición:

CompuMax

Discord: CompuMax#0425
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Buenas Max, me encanta este aporte y, en especial, que te unas a nuestro clan de ASM.

Con respecto a mejorar la rutina:
  1. Cuando llamas al "var decrypter" estás usando el offset original + 1 (por ser THUMB), sin embargo la notación que se acostumbra al cargar este tipo de rutinas (puesta muy de moda en la comunidad inglesa por FBI) es: ldr rX, =(0x08XXXXXX+1) (para tener en cuenta que el offset en realidad es el anterior y que le sumas uno por ser una rutina THUMB a la que vas a llamar). En fin, solo digo que puede ayudarte a ti y a los que lean a no perderlo de vista.
  2. Por supuesto, lo que el jefecito te ha dicho de los branches.
  3. El método que has usado de meter otro tilemap para borrar la imagen ocupa demasiado espacio, es mucho más eficiente hacer un loop que rellene con 00s (por el primer tile del tilemap). Si tienes alguna duda con eso, en otro momento te explico lo que quiero decir.
Gracias por las recomendaciones bro. Sí, por supuesto que cambiaré a ese método de colocar el offset (0x08XXXXXX+1). Y sí, estaba indeciso en que ocupaba menos espacio la rutina con el loop o la RAW que tampoco pesa mucho; obviamente no recordaba que en ASM un comando solo ocupa 2bytes :D. Pero entiendo perfectamente a lo que te refieres y estoy en la capacidad de hacerlo ;)

He ahí el punto que más me preocupa: las textboxes usan el BG0. Por lo tanto, al mostrar un mensaje en pantalla lo que debería pasar es que se borre la parte de abajo de la imagen y sea reemplazada por la textbox. En mi opinión sería más útil usar otro BG y recargarlo nuevo si quieres mostrar imágenes y textos.

En fin, saludos y felicitaciones por este gran aporte.
Efectivamente si cargo textboxes borra automáticamente toda la imágen igual si hago uso del comando showpokepic y lo recomendable sería hacer uso de otro BG. Por otra parte si uso el comando showpokepic despues de la imágen éstas comparten la pantalla sin ningún problema por lo que podría usarse perfectamente para crear Vs. Var con pokepics sin ningún problema y además darle movimiento modificando el registro I/O 4000010h que controla el scrolling horizontal del BG0.

Saludos y gracias por el apoyo!
 

CompuMax

Discord: CompuMax#0425
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Dándole duro a la rutina y revisando minuciosamente su funcionamiento conseguí un par de errores, me imagino que aún no la usan o no se han dado cuenta :D

Lo que a continuación muestro es lo que conseguí que sucede mostrado cuadro a cuadro cuando se está cargando la imágen:


No es un error de la rutina (que cree bug o algo por el estilo), lo que está ocurrió fué que no programé la rutina de la manera correcta :). Entonces pasan 2 cosas:

1) En la primera transición la imágen no se carga desde la línea 0 sino desde cualquier línea siguiente al llamar la subrutina. Esto se debe a que no se espera un V-Blank o blanqueo vertical para cargar la imágen y entonces se carga en el siguiente H-Blank o blanqueo horizontal luego de terminar de dibujar dicha línea.


2) Además se puede observar en la segunda transición (al igual que en la primera) que en el siguiente fotograma ya se carga la imágen completa pero sin la paleta correspondiente. Eso se debe a 2 cosas: el orden en que se va cargando los datos de la tabla [TileSet > TileMap > Paleta] y que la velocidad de escritura en la WRAM es más lenta que en la VRAM por lo que aún cuando tiene el tiempo de barrido vertical restante para dibujar el primer fotograma más el tiempo del V-Blank no le da tiempo de escribir los valores de las paletas en la WRAM.


Para solucionar esto se han hecho unos cuantos cambios en la rutina original (además de las correcciones y recomendaciones dadas por los que comentaron). Ahora la rutina trabaja de la siguiente manera:

Carga la Paleta > Carga el TileSet > Espera el V-Blank > Carga el TileMap

De esta manera se garantiza que se cargue primero la paleta, luego se carga el TileSet, se espera el siguiente V-Blank y finalmente se escribe el TileMap. Así se corrige los dos errores: Se carga primero la paleta y la imágen se comienza a dibujar desde la primera línea horizontal. Teniendo el resultado deseado:


Además se han añadido 3 sub-rutinas para borrar la imágen (si 3, tu elije la que te parezca) y así ahorrar el espacio ocupado por la RAW rellena de tiles transparentes que había hecho en primer lugar.

Con respecto a @Inquisidor K. Frank entiendo perfectamente lo de no tener que hacer PUSH y POP a los registros, pero por alguna razón si no lo hago la rutina se queda pegada y no retorna, aún cuando sigo haciendo PUSH {LR} y POP {PC} '^^. De seguro hay algo más que aún desconozco así que también cito a @Kaiser de Emperana, @Javi4315♪, @jiangzhengwenjz, @BLAx501! para que den su opinión y por supuesto a @Naren Jr. y @【Muerte】 Helix Boo♪ (o creían que se iban a salvar) :D

Aclaro que la mayoría de las etiquetas son para identificar lo que se va a hacer a partír de ahí y no tienen utilidad alguna a excepción de algunas como Ejecutar y como no ocupan ningún byte en la rutina no está de más dejarlas.

Ahora sí, 100% funcional y sin errores. Espero la utilicen con sabiduría y le saquen mucho provecho.

Saludos!

Max.
 

Laquin

Usuario mítico
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Felicidades por tu primera rutina, eso lo primero. No cualquiera llega a hacer una. Se ve que le has puesto ganas y empeño, y se agradece.
No sé si lo voy a usar o no, pero si lo hago no me arrepentiré.
¡Muchísimas gracias! :D
 
Última edición:

Kaiser de Emperana

Called in hand
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Por lo que veo la rutina no tiene muchos problemas. Siendo que es algo bastante simple, yo lo dejaría ahí. Con que funcione no hay porque darle tantas vueltas.

Sobre el tema de los push y pop. No hace falta que pushees los registros de r0 a r3, pero el r4 si tenés que pushearlo. Probablemente sea eso lo que hace que el juego se clave.
 

Cheve

MoonLover~
Miembro de honor
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Eres grande. Buen trabajo colega! Seguro termino usándola más de una vez
 

CompuMax

Discord: CompuMax#0425
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Por lo que veo la rutina no tiene muchos problemas. Siendo que es algo bastante simple, yo lo dejaría ahí. Con que funcione no hay porque darle tantas vueltas.

Sobre el tema de los push y pop. No hace falta que pushees los registros de r0 a r3, pero el r4 si tenés que pushearlo. Probablemente sea eso lo que hace que el juego se clave.

Wow! Gracias bro. Voy a probar si era eso, aunque tendrías que explicarme el porqué jajaja

Y sí, esta es la versión final. Quizás depende del uso que le den les de uno que otro problemita, pero si se las ingenian, incluso sin modificar las rutinas lograrán lo que desean hacer.

Eres grande. Buen trabajo colega! Seguro termino usándola más de una vez
Gracias bro. Ahorita estoy trabajando con las otras BG, sólo me falta un pequeño detalle por corregir y la pondré a la orden para que puedan usar la textbox y por supuesto varias capas, scrolling, desvanecimientos, entre otros efectos disponibles en la BIOS y ver si se animan a diseñar nuevas cosas en sus ROMs.

Saludos y a seguir hackeando!

:D
 

Sayer301!

UnityLord!
Miembro de honor
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Ya no hackeo, pero ole tus huevos tío! Una lástima que ya no hackee porque de verdad era algo que buscaba con mucho interés y que tuve que apañarmelas con tilesets. Mis dieces señoor!
 

CompuMax

Discord: CompuMax#0425
Miembro insignia
Respuesta: FR | RF [Tutorial ASM] Mostrar Imágenes a Pantalla Completa by CompuMax

Ya no hackeo, pero ole tus huevos tío! Una lástima que ya no hackee porque de verdad era algo que buscaba con mucho interés y que tuve que apañarmelas con tilesets. Mis dieces señoor!
Si bro. Tambien ví buenos hacks en progreso como el Life Version y el Ancient que se las ingeniaron con mapas de 240x160 para lograr el efecto que querían y pues aunque es válido se ve poco profesional. Como mencioné estroy puliendo las rutinas para cargar imágenes en los BG1, BG2 y BG3 para que se pueda hacer uso de la textbox tranquilamente. Espero estar posteándola por aquí pronto. De momento estoy trabajando en una rutina para mi hack así que llevará al menos una semana más.

;)
 
Arriba