Registrarse

[Rutina] [ASM][FR] Sistema de Cuentapasos con Ejecución de Scripts Integrada (SiCESI)

Fran Agustín

Si el sol besa tus ojos, ni cuenta te das.
Miembro insignia

Sistema de cuentapasos con ejecución de script integrada
Aprovechando que ayer posteé mi rutina de cuentapasos en respuesta a una duda, he decidido crear su propio tema así no se pierde. Tengan en cuenta que éste es, además, el hilo de soporte, por lo que es aquí donde deben consultarme sus dudas, problemas o sugerencias.
Información Técnica

Explicación:El Sistema de Cuentapasos con Ejecución de Script Integrada (SiCESI) es una rutina ASM que, tal y como indica su nombre, al ser activada almacena la cantidad de pasos que hayas caminado. Al alcanzar una cantidad determinada, se ejecuta el script que hayas asignado.
Nota: Es obligatorio asignar un script. Si no quieres que se ejecute absolutamente nada, simplemente compila un nop.

Compatibilidad: Fire Red (U) v1.0. Probablemente durante la semana sea adaptada para FR v1.1, Rojo Fuego, Emerald (U) y Esmeralda.

¿Recibe Parámetros?: Sí.
  • Variable 0x40FD: Es la cantidad de pasos tras la cual se ejecuta el script asignado. Aprovechándonos de ella, podemos usar el cuentapasos en diferentes oportunidades e, incluso, con distintos niveles de dificultad.
    A la vez, funciona de interruptor, si el valor es igual a 0, está apagado.
  • Variable 0x40FF: Es el orden que tiene el script a llamar dentro de la tabla, empezando a numerarlos desde el 0.

¿Devuelve Parámetros?: Sí.
  • Variable 0x40FE: En ella se almacena la cantidad de pasos que has dado desde que encendiste el cuentapasos.
    Nota: No se reinicia si apagas y vuelves a encender el cuentapasos, para eso usa un setvar 0x40FE 0.

¿Recibe Parámetros?: Sí.
  • Variable 0x40FF: No es exactamente un parámetro, pero si tiene un valor que no sea $FFFF (65535) el cuentapasos estará apagado. Al darle dicho valor, se enciende.
  • Variable 0x40FD: Es la cantidad de pasos tras la cual se ejecuta el script asignado. Aprovechándonos de ella, podemos usar el cuentapasos en diferentes oportunidades e, incluso, con distintos niveles de dificultad.

¿Devuelve Parámetros?: Sí.
  • Variable 0x40FE: En ella se almacena la cantidad de pasos que has dado desde que encendiste el cuentapasos.
    Nota: No se reinicia si apagas y vuelves a encender el cuentapasos, para eso usa un setvar 0x40FE 0.
Instrucciones de Instalación

  1. Compilar el/los script/s que deseen ejecutar.
  2. Con el offset que nos dio nuestro editor de scripts, tenemos dos maneras de proceder:
    • Editando el archivo .asm: Nos vamos a la línea en que dice "script_table" y editamos el "0x08A00000" con "0x08(offset de la tabla)", debiendo ser éste un lugar con espacio libre para rellenar con punteros a todos los scripts que quieran llamar.
    • Editando la versión compilada (archivo .bin): Nos vamos a la posición $60 (ctrl+G) y editamos "00 00 A0 08" por un pointer al offset que quieras para la tabla. Es decir, tomamos la dirección de un lugar con mucho espacio libre, lo volteamos de a 2 y lo escribimos seguido de un 08. Ejemplo: Quiero poner mi tabla en el offset 0x881823, en el lugar indicado escribiremos "23 18 88 08".
  3. Ahora debemos insertar la rutina en un espacio vacío de la ROM con un editor hexadecimal. Si seguiste la primera opción, primero debes ensamblarla.
  4. Abrimos un editor hexadecimal y vamos al offset 0x06D622, es decir, damos ctrl+G, marcamos la casilla hexadecimal, escribimos 6D622 y le damos aceptar.
  5. En dicha posición debes escribir los siguientes bytes: "01 4A 10 47 00 00 XX XX XX 08", donde XX XX XX es el offset en que insertaste la rutina permutado. Es decir, hacemos lo mismo que con el script. No olvidemos sumarle 1, de lo contrario no funcionará.
  6. Recuerda, sólo comenzará a contar los pasos si haces primero un setvar 0x40FD 0x(cantidad_de_pasos).
  7. Construyendo la tabla:
    • Buscamos un offset con mucho espacio vacío desde un editor hexadecimal.
    • Compilamos los scripts que vayamos a usar.
    • Permutamos los offsets que nuestro editor de scripts nos ha asignado.
    • Desde el editor hexadecimal vamos a la posición que asignamos en script_table (por defecto $A00000).
    • Insertamos uno a uno los punteros a los scripts, sin dejar lugar entre ellos.
  8. NOTA: El número que debemos asignar a la variable 0x40FF del script a llamar empieza desde el 0; es decir, el primer lugar de la tabla equivale al índice 0, el segundo al 1 y así suecivamente.
  1. Compilar el script que deseen ejecutar.
  2. Con el offset que nos dio nuestro editor de scripts, tenemos dos maneras de proceder:
    • Editando el archivo .asm: Nos vamos a la línea en que dice "script_adress" y editamos el "0x08784F90" con "0x08(offset del script)".
    • Editando la versión compilada (archivo .bin): Nos vamos a la posición $54 (ctrl+G) y editamos "90 4F 78 08" por un pointer a tu script. Es decir, tomamos el número que nos dio el XSE, lo volteamos de a 2 y lo escribimos seguido de un 08. Ejemplo: XSE puso mi script en el offset 0x881823, en el lugar indicado escribiremos "23 18 88 08".
  3. Ahora debemos insertar la rutina en un espacio vacío de la ROM con un editor hexadecimal. Si seguiste la primera opción, primero debes ensamblarla.
  4. Abrimos un editor hexadecimal y vamos al offset 0x06D622, es decir, damos ctrl+G, marcamos la casilla hexadecimal, escribimos 6D622 y le damos aceptar.
  5. En dicha posición debes escribir los siguientes bytes: "01 4A 10 47 00 00 XX XX XX 08", donde XX XX XX es el offset en que insertaste la rutina permutado. Es decir, hacemos lo mismo que con el script. No olvidemos sumarle 1, de lo contrario no funcionará.
  6. Recuerda, sólo comenzará a contar los pasos si haces primero un setvar 0x40FF 0xFFFF.
  7. Nota: El archivo de texto que viene incluido tiene un pequeño error, en lugar de $FFFF dice $FF; lo correcto son 4 F (equivale a 65535 en decimal).
Descarga

Link por Mediafire. Contiene la rutina en formato .asm y .bin (ensamblada) junto a un archivo de texto con las instrucciones de instalación.
Versión 1.0 (Antigua) (Mediafire). Contiene la rutina en formato .asm y .bin (ensamblada) junto a un archivo de texto con las instrucciones de instalación.
Para los que no quieran descargarla por cualquier motivo que sea.
Código:
main:
 push {r4-r7}
 ldrh r0, =0x40FD
 ldr r1, var_decrypter
 bl call_r1
 mov r4, r0
 ldrh r0, [r0]
 mov r1, #0
 cmp r0, r1
 beq end
 ldrh r0, =0x40FE
 ldr r1, var_decrypter
 bl call_r1
 mov r5, r0
 ldrh r3, [r0]
 ldrh r0, [r4]
 add r3, #1
 cmp r0, r3
 bne otropaso
 mov r0, #0
 strh r0, [r4]
 ldrh r0, =0x40FF
 ldr r1, var_decrypter
 bl call_r1
 ldrh r1, [r0]
 mov r2, #4
 mul r1, r2
 ldr r0, script_table
 add r0, r1
 ldr r0, [r0]
 ldr r1, script_executer
 bl call_r1

end:
 pop {r0-r7}
 lsl r0, r0, #0x18
 lsr r0, r0, #0x18
 cmp r0, #1
 beq brancher
 ldr r0, =0x02037078
 ldr r2, =(0x806D62C +1)
 bx r2

otropaso:
 strh r5, [r4]
 b end

brancher:
 ldr r2, =(0x806D650 +1)
 bx r2

call_r1:
 bx r1

.align 2
script_table: .word 0x08A00000
script_executer: .word 0x08069AE5
var_decrypter: .word 0x0806E455
Código:
F0 B4 1A 48 18 49 00 F0 2A F8 04 1C 00 88 00 21 88 42 18 D0 16 48 14 49 00 F0 21 F8 05 1C 03 88 20 88 01 33 98 42 16 D1 00 20 20 80 11 48 0E 49 00 F0 15 F8 01 88 04 22 51 43 09 48 40 18 00 68 08 49 00 F0 0C F8 FF BC 00 06 00 0E 01 28 04 D0 09 48 0A 4A 10 47 25 80 F5 E7 09 4A 10 47 08 47 00 00 A0 08 E5 9A 06 08 55 E4 06 08 FD 40 00 00 FE 40 00 00 FF 40 00 00 78 70 03 02 2D D6 06 08 51 D6 06 08
Para los que no quieran descargarla por cualquier motivo que sea.
Código:
main:
 push {r0-r7}
 ldrh r0, =0x40FF
 ldr r1, var_decrypter
 bl call_r1
 ldrh r0, [r0]
 ldrh r1, =0xFFFF
 cmp r0, r1
 bne end
 ldrh r0, =0x40FE
 ldr r1, var_decrypter
 bl call_r1
 mov r4, r0
 ldrh r5, [r0]
 ldrh r0, =0x40FD
 ldr r1, var_decrypter
 bl call_r1
 ldrh r0, [r0]
 add r5, #1
 cmp r0, r5
 bne otropaso
 mov r0, #0
 strh r0, [r4]
 ldr r0, script_adress
 ldr r1, script_executer
 bl call_r1

end:
 pop {r0-r7}
 lsl r0, r0, #0x18
 lsr r0, r0, #0x18
 cmp r0, #1
 beq brancher
 ldr r0, =0x02037078
 ldr r2, =(0x806D62C +1)
 bx r2

otropaso:
 strh r5, [r4]
 b end

brancher:
 ldr r2, =(0x806D650 +1)
 bx r2

call_r1:
 bx r1

.align 2
script_adress: .word 0x08784F90
script_executer: .word 0x08069AE5
var_decrypter: .word 0x0806E455
Código:
FF B4 17 48 15 49 00 F0 24 F8 00 88 15 49 88 42 13 D1 15 48 11 49 00 F0 1C F8 04 1C 05 88 13 48 0E 49 00 F0 16 F8 00 88 01 35 A8 42 0D D1 00 20 20 80 08 48 08 49 00 F0 0C F8 FF BC 00 06 00 0E 01 28 04 D0 0A 48 0B 4A 10 47 25 80 F5 E7 0A 4A 10 47 08 47 90 4F 78 08 E5 9A 06 08 55 E4 06 08 FF 40 00 00 FF FF 00 00 FE 40 00 00 FD 40 00 00 78 70 03 02 2D D6 06 08 51 D6 06 08

 
Última edición:

Kaiser de Emperana

Called in hand
Buen aporte, pero me parece que estás desperdiciando dos variables xD
En vez de llevar un contador ascendente, yo llevaría uno descendente; así en vez de comparar dos valores de variables, valuás una en la cantidad de pasos y la comparás contra 0.
La cantidad de pasos dada sería tan facil como hacer un valor_máx - valor_actual desde el script.Podrías hasta hacer un script que lo calcule y lo guarde en lastresult, sólo habría que hacerle call.

Y el hecho de que el contador esté encendido o no, sería tambien el comparar la variable con 0, si es 0 está apagado y no hace falta restar.

Algo así:
Código:
main:
 push {r0-r7}
 ldrh r0, =0x40FF
 ldr r1, var_decrypter
 bl call_r1

 ldrh r1, [r0]
 cmp r1, #0
 beq end
 sub r1, #1
 strh r1, [r0]
 cmp r1, #0
 bne end

 ldr r0, script_adress
 ldr r1, script_executer
 bl call_r1

end:
 pop {r0-r7}
 lsl r0, r0, #0x18
 lsr r0, r0, #0x18
 cmp r0, #1
 beq brancher
 ldr r0, =0x02037078
 ldr r2, =(0x806D62C +1)
 bx r2

brancher:
 ldr r2, =(0x806D650 +1)
 bx r2

call_r1:
 bx r1

.align 2
script_adress: .word 0x08784F90
script_executer: .word 0x08069AE5
var_decrypter: .word 0x0806E455
(No probé ni si compila, pero a no ser que tenga un error MUY tonto, creo que debería andar bien)
 
Última edición:

H.B.P

Emperador Kaktiácero
Miembro de honor
Grandiosa aportación, se pueden hacer muchas cosas con un script como éste. Hace tiempo que se piensa en un tipo de script donde desafías a otros "jugadores" en carreras, pero quizás aplicar este método para ello sea algo rudimentario, no sé si habrían "parones".

+Gracias.
 

pikachu240

Junior C# Developer
Me ha gustado pero me he quedado pensado que el script esta fijo y no se puede poner otro mediante scripting...lo digo para que se pueda usar en mas situaciones...porque en una variable no cave un offset no? O en dos la verdad es que no se como vs el asm pero me gusta que se puedan usar para mas cosas los programas.
 

Bugrhak

A long time ago I used to call myself "Subzero".
Me ha gustado pero me he quedado pensado que el script esta fijo y no se puede poner otro mediante scripting...lo digo para que se pueda usar en mas situaciones...porque en una variable no cave un offset no? O en dos la verdad es que no se como vs el asm pero me gusta que se puedan usar para mas cosas los programas.
Así como está, la rutina solo carga un script.
Puedes claro,usar este script para que llame a sub scripts, para así contrarrestar el hecho del único script. Pero esto sería ineficiente.

Lo ideal sería usar una tabla de punteros donde cada uno de estos llevaría a cada script en cuestión.
Y bueno, para determinar que script se carga desde la tabla, usas una variable (puede ser dinámica o no, dependiendo de lo que quieras, porque si recuerdas, las vars dinámicas se resetean al entrar a un mapa o al abrir un menú...).
Y hablando de variables, no, nunca vas a cargar un puntero en una (sería ilógico) porque una variable es un Hword, y un puntero es un Word...


--------------------------------------------​


Hace casi un año que estaba buscando esto! Las posibilidades para lo que puedes aplicar esto, son muchas :D
¡Le daré buen uso, gracias por compartirlo!
 
Última edición:

pikachu240

Junior C# Developer
Lo de la tabla y una variable que diga que script toca me gusta eso da flexibilidad a la rutina haciéndola mas versátil :) yo.creo que los programas tienen que poder reutilizarse y con esta idea, la de la tabla, creo que será el punto que lo convertirá en util para muchos proyectos :)
 

Fran Agustín

Si el sol besa tus ojos, ni cuenta te das.
Miembro insignia

Sistema de cuentapasos con ejecución de script integrada
★★Helix Boo★★;390572 dijo:
Grandiosa aportación, se pueden hacer muchas cosas con un script como éste. Hace tiempo que se piensa en un tipo de script donde desafías a otros "jugadores" en carreras, pero quizás aplicar este método para ello sea algo rudimentario, no sé si habrían "parones".

+Gracias.
No veo cómo podría aplicarse a ello, sinceramente. No tendrías manera de medir la velocidad ni hacerlos correr en simultáneo. En fin, que no está hecho para eso xD
Me ha gustado pero me he quedado pensado que el script esta fijo y no se puede poner otro mediante scripting...lo digo para que se pueda usar en mas situaciones...porque en una variable no cave un offset no? O en dos la verdad es que no se como vs el asm pero me gusta que se puedan usar para mas cosas los programas.
Pues, como dijo Sub, la idea original era que la estructura condicional funcionara dentro del propio script. Por supuesto que está pensado para usarse en muchas oportunidades, sólo que no desde la estructura ASM.

Buen aporte, pero me parece que estás desperdiciando dos variables xD
En vez de llevar un contador ascendente, yo llevaría uno descendente; así en vez de comparar dos valores de variables, valuás una en la cantidad de pasos y la comparás contra 0.
La cantidad de pasos dada sería tan facil como hacer un valor_máx - valor_actual desde el script.Podrías hasta hacer un script que lo calcule y lo guarde en lastresult, sólo habría que hacerle call.

Y el hecho de que el contador esté encendido o no, sería tambien el comparar la variable con 0, si es 0 está apagado y no hace falta restar.
Yo creo que no deja de ser útil tener las cantidades en dos variables diferentes, a la larga ahorra espacio en los scripts y evita que se vuelvan incomprensibles de tantas cuentas extrañas (que si incluso hiciéramos distintos niveles de dificultad tendríamos que plantear como estructura condicional).
Actualización

Buenas, he venido aquí para anunciar una nueva versión del SiCESI. Siguiendo sus comentarios he mejorado la rutina permitiendo la carga del offset desde una tabla usando para pasar el índice la variable que liberé al usar de interruptor la misma que contiene el limitador de pasos.

Ya está el post principal editado con el nuevo link de descarga y las modificaciones.
 

H.B.P

Emperador Kaktiácero
Miembro de honor
Espero no decir ningún disparate, pero en lugar de contar pasos, podríamos hacer que el sistema cuente minutos de juego o algo así (para el cálculo, le restaríamos la cantidad inicial de minutos jugados a la cantidad final). De esta forma, podríamos simular eventos determinados por el tiempo, como un evento donde tengas que salir de un lugar en ruinas o incluso una carrera.
 

pikachu240

Junior C# Developer
★★Helix Boo★★;391110 dijo:
Espero no decir ningún disparate, pero en lugar de contar pasos, podríamos hacer que el sistema cuente minutos de juego o algo así (para el cálculo, le restaríamos la cantidad inicial de minutos jugados a la cantidad final). De esta forma, podríamos simular eventos determinados por el tiempo, como un evento donde tengas que salir de un lugar en ruinas o incluso una carrera.
Eso estaria bien pero creo que seria otra rutina, esta en si es necesaria que exista :)
 

KanaCn

由紀カクタス
Muchas gracias por compartirlo, se me hará más fácil hacer un nuevo punto de Safari xD.

-Yuki
 
Arriba