es/Dynamic X: Difference between revisions
(66 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{Select Language|Dynamic_X}} | |||
Dynamic X es un sistema avanzado de manejo de carga dinámica cuyo propósito es otorgar soporte a la transferencia de gráficos y paletas de colores a la VRAM y CGRAM respectivamente. Este sistema vendría a reemplazar al Dynamic Z V3.7 que a su ves es un reemplazo del DSX. | Dynamic X es un sistema avanzado de manejo de carga dinámica cuyo propósito es otorgar soporte a la transferencia de gráficos y paletas de colores a la VRAM y CGRAM respectivamente. Este sistema vendría a reemplazar al Dynamic Z V3.7 que a su ves es un reemplazo del DSX. | ||
== Descarga == | |||
* [https://snestorage.com/index.php Dynamic X Website] | |||
== Funcionalidades == | == Funcionalidades == | ||
* Cargar Poses Dinámicamente: Permite cargar poses para Sprites Dinámicos desde cualquier código ASM. | * Cargar Poses Dinámicamente: Permite cargar poses para Sprites Dinámicos desde cualquier código ASM. | ||
Line 14: | Line 17: | ||
== Requisitos == | == Requisitos == | ||
* [https://dotnet.microsoft.com/en-us/download/dotnet/7.0 .Net 7] | * [https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-7.0.306-windows-x86-installer .Net 7 x86] | ||
== Instalación == | == Instalación == | ||
=== Pasos Generales === | |||
Antes de instalar el Dynamic X. | |||
# El ROM debe tener instalado SA-1 Pack. | |||
# Poner todos los archivos con extensión ".drawinfo" en la carpeta "DrawInfo". | |||
# Poner todos los archivos con extensión ".dynamicinfo" en la carpeta "DynamicInfo". | |||
# Poner todos los archivos con extension ".paleffect" en la carpeta "PaletteEffects". | |||
# Poner todos los archivos de recursos como GFXs y Paletas de colores que tienen extension ".bin" en la carpeta "DynamicResources". | |||
==== Usando el Tool Directamente ==== | |||
Puedes instalar el Dynamic X dándole abriendo el archivo "DynamicXTool.exe", al hacerlo se te abrirá una consola diciéndote que escribir en cada momento. Iniciara preguntandote por los paths del ROM, carpeta de Pixi, UberasmTool o GPS (estos ultimos 3 son optativos) y luego te preguntara por los features que quieres instalar, pon "y" o "yes" para habilitar cada feature y "n" o "no para deshabilitar ese feature. | |||
'''Advertencia''': Los features como Player Features y Status Bar Optimization, pueden tener incompatibilidades con otros recursos, así que debes tener cuidado al instalarlos. Tener cuidado con que features instalan. | |||
==== Usando el Tool Desde Consola ==== | |||
Debes llamar el comando: | |||
<pre> | |||
DynamicXTool -use-settings | |||
</pre> | |||
El ROM se instalara con los settings default si nunca se ha hecho una instalación previa, si se ha hecho una instalación previa, entonces se usaran los settings usados en esa instalación. | |||
===== Settings ===== | |||
En caso de querer cambiar los settings manualmente debes abrir el archivo settings.json que se vera así: | |||
<pre> | |||
{ | |||
"InputROMPath": "", | |||
"OutputROMPath": "", | |||
"PixiPath": "", | |||
"UberasmToolPath": "", | |||
"GPSPath": "", | |||
"GraphicChange": true, | |||
"PaletteChange": true, | |||
"PaletteEffects": true, | |||
"DynamicPoses": true, | |||
"DrawingSystem": true, | |||
"ControllerOptimization": true, | |||
"FixedColorOptimization": true, | |||
"StatusBarOptimization": false, | |||
"ScrollingOptimization": true, | |||
"PlayerFeatures": false | |||
} | |||
</pre> | |||
Debes cambiar los parámetros según los settings que desees. | |||
== Mejoras en Comparación a otros sistemas == | == Mejoras en Comparación a otros sistemas == | ||
=== Dynamic X VS DSX === | |||
* Dynamic X contiene muchos features que DSX no posee. El DSX solo posee soporte para sprites dinámicos. Por favor ver capitulo [https://sneslab.net/mw/index.php?title=es/Dynamic_X&action=edit§ion=1 Funcionalidades]. | |||
* DSX permite máximo 4 sprites dinámicos de 32x32, 2 de 48x48 o 1 de 64x64. Dynamic X tiene menos limitaciones en el número de sprites, primero por que todos los sprites comparten poses, por lo tanto, si hay 2 sprites iguales es muy probable que puedas usar todos los que quieras en pantalla sin problemas, segundo puedes decirle al Dynamic X que espacio dinámico usar y dependiendo de ese espacio tienes más o menos limite para sprites dinámicos, de hecho, no existe un limite para sprites dinámicos como tal debido a que si un sprite no puede cargar una pose en la vram, usa la ultima pose que logro cargar, por lo tanto, en el peor de los casos el sprite quedaría con su pose congelada por un momento hasta que sea capaz de cargar una nueva pose. | |||
* DSX requiere copiar una rutina a todos los sprites que usan su sistema, Dynamic X es solo llamar una rutina de la API, en 3 lineas de codigo puedes subir una pose a la VRAM y dibujar esa pose, eso hace al Dynamic X mucho más eficiente en ROM. | |||
* DSX no tiene sistema de dibujado, el sprite debe tener su propia rutina gráfica, lo que no solo hace que cada pose dinámica sea solo utilizable dentro del contexto del sprite, sino que gasta mucha más ROM al tener que hacer esa rutina gráfica. Dynamic X por otro lado, permite cargar cualquier pose dinámica y dibujarla desde cualquier código ASM, lo que le da mucha más flexibilidad de uso y además al tener un sistema centralizado de dibujo, se ahorra mucho espacio en ROM. | |||
* El DSX permite como máximo, cargar poses dinámicas de 64x64 (16 tiles de 16x16), Dynamic X no tiene un limite, si puedes optimizar el NMI handler podrías teóricamente hacer poses de hasta 96x96 (32~36 tiles de 16x16), aunque sin optimizaciones fuertes y solo desactivando las exanimations vanilla, podrías conseguir un sprite 80x80 (24~25 tiles de 16x16). | |||
* Los gráficos del Dynamic X, son optimizados, esto significa que a pesar de no estar comprimidos con algoritmos como LZ, si usan la menor cantidad de tiles de 16x16 y 8x8 posibles, por lo tanto, esto permite utilizar sprites más grandes y optimizar las transferencias a la VRAM, lo que aumenta su capacidad de tener más poses dinámicas cargadas en la VRAM. El DSX por su parte, los gráficos no tienen ningún tipo de optimización y suelen malgastar mucho espacio con zonas en blanco. | |||
* El DSX usa un buffer que luego es enviado a la VRAM, esto es un problema debido a que generar ese buffer es muy lento y requiere muchos ciclos, además el DSX debe generar este buffer en cada frame, por lo que un sprite dinámico hecho para DSX suele ser muy lento y utilizar muchos recursos, incluso utilizando SA-1 podrías tener problemas de slowdown si utilizas sprites dinámicos y algún efecto de hdma que sea complejo como un parallax o un wave. El Dynamic X no utiliza un buffer, si no que usa cola de transferencias que se carga directamente a la VRAM sin buffers intermedios, no solo eso, sino que cada pose es cargada solo cuando es necesario, por lo tanto, la carga no se hace en cada frame, sino cuando es necesario, además en ciertos sprites puedes sincronizar la animación para que todos usen exactamente la misma pose o una pose que ya esta cargada en la VRAM, esto reduce considerablemente el slowdown. | |||
=== Dynamic X VS Dynamic Z V3.7 === | |||
== Formatos == | == Formatos == | ||
=== Dynamic Info === | |||
Los archivos con extensión ".dynamicinfo" se utilizan para insertar gráficos de poses, paletas y otros recursos en el ROM. Además incluyen la información necesaria para que las poses sean cargadas correctamente en la VRAM. | |||
El formato de estos archivos es el siguiente: | |||
<pre> | |||
PosesGraphics: | |||
... | |||
Palettes: | |||
... | |||
Resources: | |||
... | |||
PosesChunksSizes: | |||
... | |||
</pre> | |||
* '''PosesGraphics''': Debajo de este label va cada archivo de gráficos utilizado para cargar poses dinámicas. Ejemplo: | |||
<pre> | |||
PosesGraphics: | |||
DKCKlaptrap.bin | |||
</pre> | |||
* '''Palettes''': Debajo de este label va cada archivo de paletas de colores utilizado para las poses dinámicas. Ejemplo: | |||
<pre> | |||
Palettes: | |||
DKCKlaptrapPal1.bin | |||
DKCKlaptrapPal2.bin | |||
DKCKlaptrapPal3.bin | |||
DKCKlaptrapPal4.bin | |||
DKCKlaptrapPal5.bin | |||
</pre> | |||
* '''Resources''': Debajo de este label va cada archivo extra que se utilice como recurso y que se desee insertar en el ROM. Ejemplo: | |||
<pre> | |||
Resources: | |||
Geno.bin | |||
GenoPal.bin | |||
FireGenoPal.bin | |||
GenoPalPlayer2.bin | |||
FireGenoPalPlayer2.bin | |||
</pre> | |||
* '''PosesSizes''': Debajo de este archivo van 2 líneas por cada pose, la primera linea es un label que describe la pose y la segunda linea son 2 valores, cada uno de estos valores indica cuantos tiles de 8x8 se usan en cada chunk, cada pose dinámica tiene 2 chunks de data generalmente (excepto algunas excepciones que pueden requerir solo 1 chunk), el chunk de arriba y el chunk de abajo. El chunk de arriba son todos los tiles de 8x8 que están antes de la ultima linea de 8 pixeles de alto, mientras que el chunk de abajo es la ultima linea. En el siguiente ejemplo se pueden ver 3 imagenes, la de la izquierda es como deberia verse la imagen ensamblada, la segunda es como se veria en la VRAM y la tercera es como estaria guardado en el archivo binario, tambien mostraria como son los poses sizes de esa pose, que en este caso serian 8 tiles del chunk de arriba y 8 tiles del chunk de abajo: | |||
[[File:diagram1.png|center]] | |||
<pre> | |||
PosesChunksSizes: | |||
Frame0_PoseChunksSizes: | |||
db $08,$08 | |||
</pre> | |||
Nota: Para poses cuyo número de tiles de 8x8 sea divisible por 32, se puede usar solo el chunk de arriba que tiene todos los tiles y el chunk de abajo quedaria en 0. | |||
=== Draw Info === | |||
Los archivos con extensión ".drawinfo", tienen la información necesaria para dibujar poses, estas poses pueden ser dinámicas o poses estáticas. El Dynamic X utiliza estos archivos para generar rutinas gráficas optimizadas para cada pose, el tool detecta si es necesaria o no una de las tablas, elimina data redundante o que no aporta, encasilla cada pose en un grupo que comparte características similares y luego inserta una rutina gráfica por cada grupo de poses que comparten características similares. | |||
El formato del archivo es el siguiente: | |||
<pre> | |||
Dynamic: | |||
... | |||
Tiles: | |||
... | |||
XDisplacements: | |||
... | |||
YDisplacements: | |||
... | |||
Sizes: | |||
... | |||
Properties: | |||
... | |||
</pre> | |||
* '''Dynamic''': Si es true es dinámica, si es false es estatica, ejemplo: | |||
<pre> | |||
Dynamic: | |||
true | |||
</pre> | |||
* '''Tiles''': Es una tabla que indica que tiles utiliza cada pose, en el caso de las poses dinámicas debe considerarse que el tile de más arriba a la izquierda es el tile <code>$00</code>, esta tabla contiene 2 líneas por cada pose, la primera línea es <code>PoseName_Tiles:</code> y la segunda línea seria cada uno de los tiles utilizado por la pose. Esta tabla es optativa y en caso de que no este, utilizara el valor <code>$00</code> para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32: | |||
<pre> | |||
Tiles: | |||
Pose32x32_Tiles: | |||
db $00,$02,$04,$06 | |||
</pre> | |||
* '''XDisplacements''': Es una tabla que indica el desplazamiento horizontal de cada tile con respecto a la posición de la pose y contiene 2 líneas por cada pose, la primera línea es <code>PoseName_XDisp:</code> y la segunda línea es un valor por cada tile de la pose indicando cuanto debe moverse horizontalmente cada tile con respecto a la posición de la pose, adicionalmente se pueden añadir 2 líneas más por cada pose para cuando la pose es volteada horizontalmente, el formato es el mismo de las 2 líneas anteriores solo que la primera línea es <code>PoseName_XDispFlipX:</code>. Esta tabla es optativa y en caso de no existir, utilizara el valor <code>$00</code> para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32 y permitiendo volteo horizontal: | |||
<pre> | |||
XDisplacements: | |||
Pose32x32_XDisp: | |||
db $00,$10,$00,$10 | |||
Pose32x32_XDispFlipX: | |||
db $10,$00,$10,$00 | |||
</pre> | |||
* '''YDisplacements''': Es una tabla que indica el desplazamiento vertical de cada tile con respecto a la posición de la pose y contiene 2 líneas por cada pose, la primera línea es <code>PoseName_YDisp:</code> y la segunda línea es un valor por cada tile de la pose indicando cuanto debe moverse verticalmente cada tile con respecto a la posición de la pose, adicionalmente se pueden añadir 2 líneas más por cada pose para cuando la pose es volteada verticalmente, el formato es el mismo de las 2 líneas anteriores solo que la primera línea es <code>PoseName_YDispFlipY:</code>. Esta tabla es optativa y en caso de no existir, utilizara el valor <code>$00</code> para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32 y permitiendo volteo vertical: | |||
<pre> | |||
YDisplacements: | |||
Pose32x32_YDisp: | |||
db $00,$00,$10,$10 | |||
Pose32x32_YDispFlipY: | |||
db $10,$10,$00,$00 | |||
</pre> | |||
* '''Sizes''': Es una tabla que indica el tamaño de cada uno de los tiles que se utiliza, cada valor es <code>$00</code> para tiles de 8x8 y <code>$02</code> para tiles de 16x16. Contiene 2 líneas por cada pose, la primera línea es <code>PoseName_Sizes:</code> y la segunda línea es un valor por cada tile de la pose indicando el tamaño de cada tile. Esta tabla es optativa y en caso de no existir, utilizara el valor <code>$02</code> para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32: | |||
<pre> | |||
Sizes: | |||
Pose32x32_Sizes: | |||
db $02,$02,$02,$02 | |||
</pre> | |||
* '''Properties''': Es una tabla que indica las propiedades de cada tile, las propiedades siguen el formato YXCCPPPT, donde X es si el tile es volteado horizontalmente, Y es si el tile es volteado verticalmente, CC es la prioridad con respecto al layer 1 y layer 2, donde 00 es la prioridad más baja y 11 es la más alta, CCC es la paleta de colores usada por el tile y T es 1 para usar SP3/SP4 y 0 para SP1/SP2. Contiene 2 líneas por cada pose, la primera línea es <code>PoseName_Sizes:</code> y la segunda línea es un valor por cada tile de la pose indicando la propiedad de cada tile. Esta tabla es optativa y en caso de no existir, utilizara el valor que se entregue en el <code>!PropParam</code> para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32: | |||
<pre> | |||
Properties: | |||
Pose32x32_Properties: | |||
db $20,$20,$20,$20 | |||
</pre> | |||
=== Palette Effect === | |||
Los archivos con extensión ".paleffect" son archivos json que se utilizan para múltiples efectos de paletas de colores, tanto globales como normales, estos archivos pueden ser creados utilizando el tool "Palette Effect Creator" que es incluido al Dynamic X. | |||
El formato de estos archivos es el siguiente: | |||
<pre> | |||
{ | |||
"Name": ..., | |||
"Effects": [...] | |||
} | |||
</pre> | |||
* '''Name''': Es el nombre del conjunto de efectos de paletas de colores. Ejemplo: | |||
<pre> | |||
"Name": "DecreaseSaturation", | |||
</pre> | |||
* '''Effects''': Es una lista con cada uno de los efectos de paletas de colores, estos tienen 7 parámetros, los primeros 3 son Channel1, Channel2 y Channel3 que son valores entre 0 y 31 que indican el valor de cada canal, en el caso de un efecto RGB, el Channel1 es R, el Channel2 es G y el channel3 es B, en el caso de un efecto HSL, el Channel1 es H, el Channel2 es S y el Channel3 es L, luego vienen 3 valores más, el Ratio1, Ratio2 y Ratio3, cada uno de estos es un número entre 0 y 31 indicando cuanto afecta cada Channel a los colores de la paleta de colores, donde 0 es que afecta en un 0% y 31 es que afecta en un 100%, por ultimo Channels es para indicar si es un efecto RGB o HSL, 0 es RGB y 1 es HSL. El sguiente ejemplo muestra 2 efectos HSL que disminuyen la saturación: | |||
<pre> | |||
"Effects": [ | |||
{ | |||
"Channel1": 0, | |||
"Channel2": 0, | |||
"Channel3": 0, | |||
"Ratio1": 0, | |||
"Ratio2": 30, | |||
"Ratio3": 0, | |||
"Channels": 1 | |||
}, | |||
{ | |||
"Channel1": 0, | |||
"Channel2": 0, | |||
"Channel3": 0, | |||
"Ratio1": 0, | |||
"Ratio2": 31, | |||
"Ratio3": 0, | |||
"Channels": 1 | |||
} | |||
] | |||
</pre> | |||
=== Palette Effect Creator === | |||
Puedes encontrar el tool en el sitio web oficial de Dynamic X: | |||
*[https://snestorage.com/index.php Palette Effect Creator] | |||
== Modo de Uso == | == Modo de Uso == | ||
=== Carga Dinámica de Poses === | === Carga Dinámica de Poses === | ||
==== Cambiar Configuración de Espacio para Poses Dinámicas ==== | |||
=== Dibujar Poses === | === Dibujar Poses === | ||
=== Carga y Dibujo de Poses en Sprites === | === Carga y Dibujo de Poses en Sprites === | ||
Los sprites (Sprites normales, clusters y extended) poseen rutinas especiales que se insertan en las Shared Routines de Pixi al momento de instalar el Dynamic X, estas rutinas simplifican considerablemente el trabajar con poses dinámicas y con el sistema de dibujo del Dinamic X. | |||
==== Upload ==== | |||
La primera rutina es '''Upload''', esta rutina carga en el espacio destinado para poses Dinámicas, la pose que deseas. Posee 2 versiones el '''Upload''' normal y el '''UploadWithoutPoseOffset''' | |||
<ul> | |||
<li> | |||
'''Upload''' | |||
<ul> | |||
<li> | |||
'''Versiones''': %DXNormalUpload(), %DXClusterUpload(), %DXExtendedUpload(). | |||
</li> | |||
<li> | |||
'''Input''': | |||
<ul> | |||
<li> | |||
'''A''': ID de la pose base (16 bits). Se puede usar el define autogenerado por Dynamic X que es <code>!DynamicPoseID<Nombre del Dynamic Info>000</code>. Ejemplo: <code>!DynamicPoseIDDKCKlaptrap000</code>. | |||
</li> | |||
<li> | |||
'''!PoseIndex,x''': La pose dentro del contexto que se desea cargar. Se calcula la pose como <code>A + !PoseIndex,x</code>. Por ejemplo si deseamos la pose 5 de Klaptrap en A se pondria <code>!DynamicPoseIDDKCKlaptrap000</code> y en <code>!PoseIndex,x</code> pondriamos el valor <code>$05</code>. | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
'''Output''': | |||
<ul> | |||
<li> | |||
'''Carry''': Si despues de la rutina hay un Carry Set, puede significar 3 cosas: | |||
<ul> | |||
<li> | |||
La pose fue cargada con éxito. | |||
</li> | |||
<li> | |||
La pose ya estaba cargada previamente y se esta reutilizando. | |||
</li> | |||
<li> | |||
La pose no fue cargada y no fue encontrada, pero en un ciclo anterior si se cargo una pose en la VRAM y se puede usar. | |||
</li> | |||
</ul> | |||
Si el Carry es un Carry Clear, la pose no pudo ser cargada y previamente no se cargo ninguna pose, en este caso lo recomendable seria despawnear el sprite, excepto si es un Boss o un sprite que debe ser persistente en el nivel. | |||
</li> | |||
<li> | |||
'''!LastPoseIndex,x''': Tendrá el valor de la ultima pose que fue cargada a la VRAM. Al momento de dibujar o de hacer una rutina de interacción que tenga cajas de colisión dependientes de la pose, se debería utilizar esta tabla. Si es <code>$FF</code> entonces nunca se ha cargado una pose previamente. | |||
</li> | |||
<li> | |||
'''!LastPoseHashIndex,x''': Es de uso interno, pero básicamente contendrá el valor del ID que indexa la tabla hash de poses de la ultima pose que fue cargada. Si es <code>$FF</code> entonces nunca se ha cargado una pose previamente. Si es <code>$FF</code> entonces nunca se ha cargado una pose previamente. | |||
</li> | |||
<li> | |||
'''!LastFlip,x''': Es el valor de <code>!GlobalFlip,x XOR !LocalFlip,x</code> que tenia la ultima pose que fue cargada. Al momento de dibujar o de hacer una rutina de interacción que tenga cajas de colisión dependientes de la pose, se debería utilizar esta tabla. Si es <code>$FF</code> entonces nunca se ha cargado una pose previamente. | |||
</li> | |||
<li> | |||
'''$04''': Tendra el valor <code>$00</code> si el primer tile de la pose esta cargado en SP1 o SP2, o <code>$01</code> si el primer tile de la pose fue cargado en SP3 o SP4. | |||
</li> | |||
<li> | |||
'''$08''': Tiene el Offset del primer Tile que se cargo en la pose. | |||
</li> | |||
</ul> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
'''UploadWithoutPoseOffset''' | |||
<ul> | |||
<li> | |||
'''Versiones''': %DXNormalUploadWithoutPoseOffset(), %DXClusterUploadWithoutPoseOffset(), %DXExtendedUploadWithoutPoseOffset(). | |||
</li> | |||
<li> | |||
'''Input''': | |||
<ul> | |||
<li> | |||
'''A''': ID de la pose deseada (16 bits). Puedes utilizar los defines autogenerados por Dynamic X para la pose que inician con <code>!DynamicPoseID</code>. | |||
</li> | |||
</ul> | |||
<li> | |||
'''Outputs''': Los mismos de '''Upload'''. | |||
</li> | |||
</ul> | |||
</li> | |||
</ul> | |||
==== Draw ==== | |||
La segunda rutina es '''Draw''', esta rutina se encarga de dibujar una pose, puede recibir ciertos parámetros para cambiar las propiedades, la posición o la prioridad de la pose. Tiene 2 versiones distintas '''Draw''' y '''DrawWithOffset'''. | |||
<ul> | |||
<li> | |||
'''Draw''' | |||
<ul> | |||
<li> | |||
'''Versiones''': %DXNormalDraw(), %DXClusterDraw(), %DXExtendedDraw() | |||
</li> | |||
<li> | |||
'''Inputs''': | |||
<ul> | |||
<li> | |||
</li> | |||
<li> | |||
</li> | |||
</ul> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
'''DrawWithOffset''' | |||
<ul> | |||
<li> | |||
'''Versiones''': %DXNormalDrawWithOffset(), %DXClusterDrawWithOffset(), %DXExtendedDrawWithOffset() | |||
</li> | |||
</ul> | |||
</li> | |||
</ul> | |||
=== Carga de Gráficos === | === Carga de Gráficos === | ||
=== Carga de Paletas === | === Carga de Paletas === | ||
=== | === Paletas de Sprites === | ||
==== Asignación de Paletas ==== | |||
===== Restringir Sobre escritura de Paletas ===== | |||
=== Efectos de paletas === | === Efectos de paletas === | ||
=== Cambiar Gráficos del Player usando un GFX similar al GFX32 === | === Cambiar Gráficos del Player usando un GFX similar al GFX32 === | ||
=== Cambiar Gráficos del Player === | === Cambiar Gráficos del Player === | ||
=== Cambiar Paleta del Player === | === Cambiar Paleta del Player === | ||
Latest revision as of 00:44, 20 January 2024
English | Português | Español | 日本語 |
Dynamic X es un sistema avanzado de manejo de carga dinámica cuyo propósito es otorgar soporte a la transferencia de gráficos y paletas de colores a la VRAM y CGRAM respectivamente. Este sistema vendría a reemplazar al Dynamic Z V3.7 que a su ves es un reemplazo del DSX.
Descarga
Funcionalidades
- Cargar Poses Dinámicamente: Permite cargar poses para Sprites Dinámicos desde cualquier código ASM.
- Dibujar Poses: Permite dibujar cualquier pose que este registrada en el sistema en cualquier lugar de la pantalla y desde cualquier código ASM. La forma de dibujar esta totalmente optimizada para cada pose, básicamente todas las poses que tienen características similares, usan la misma rutina grafica para optimizar ciclos y que sea lo más eficiente posible, además de disminuir considerablemente la cantidad de ROM utilizada en rutinas graficas, ya que, 1 rutina grafica puede dibujar cientos de poses distintas que pertenecen a distintos Sprites.
- Cargar Gráficos a la VRAM.
- Cargar Paletas de Colores a la CGRAM.
- Asignación Automática de Paletas: Cuando un Sprite carga una paleta, puede pedir al sistema que le asigne una paleta de forma automatizada, este buscara una paleta libre y podrá ser usada por el Sprite, en caso que la paleta ya este cargada en la CGRAM cargada entonces le dará al Sprite esa paleta. El sistema informa si no hay paletas disponibles, de esta manera, se puede evitar que el Sprite intente funcionar con paletas erróneas.
- Efectos de Paletas de Colores: Se puede editar las paletas que están cargadas para que cambien atributos como el Hue (Tinte), la Saturación y el Brillo, se pueden ponderar con un color preestablecido o también quitarle potencia a ciertos canales RGB o HSL.
- Registro de Gráficos y Paletas: El sistema permite insertar gráficos y paletas en el ROM, al hacerlo quedan disponibles la posición en que fueron guardados en el ROM y además puedes saber el ID con que fue registrado en el sistema, puedes utilizar ese ID para cargar dinámicamente esos gráficos. Dynamic X se hará cargo de eliminar los gráficos y paletas guardados previamente por el sistema e insertar los nuevos gráficos y paletas en un lugar libre en la ROM.
Funcionalidades que pueden tener problemas de compatibilidad
- Gráficos Custom para el Player: Dynamic X permite tanto cambiar los gráficos del player usando un EXGFX similar al GFX32 estando limitado a que use el tamaño y la cantidad de poses del juego Vanilla o simplemente deshabilitar completamente la carga dinámica de gráficos del player, yoshi o podoboos para hacer tu propia rutina dinámica para un player custom sin limitaciones de tamaño o cantidad de poses. Esta funcionalidad permite cambiar los gráficos en cualquier momento, por lo que podrías usar distintos players en distintos niveles o en distintas zonas del mismo nivel.
- Paletas Custom para el Player: Dynamic X te permite cambiar la paleta de colores del player libremente.
- Optimizaciones del DMA del Player: Dynamic X disminuye considerablemente los ciclos utilizados por el NMI handler, ya que, los gráficos del player, yoshi y podoboos solo son cargados en la VRAM cuando son requeridos, no siempre como ocurre en el juego Vanilla. Esto además te deja algunos tiles extras en el SP1 en niveles que no utilicen a yoshi o podoboos, incluso un tile extra en niveles que no usen la capa.
Requisitos
Instalación
Pasos Generales
Antes de instalar el Dynamic X.
- El ROM debe tener instalado SA-1 Pack.
- Poner todos los archivos con extensión ".drawinfo" en la carpeta "DrawInfo".
- Poner todos los archivos con extensión ".dynamicinfo" en la carpeta "DynamicInfo".
- Poner todos los archivos con extension ".paleffect" en la carpeta "PaletteEffects".
- Poner todos los archivos de recursos como GFXs y Paletas de colores que tienen extension ".bin" en la carpeta "DynamicResources".
Usando el Tool Directamente
Puedes instalar el Dynamic X dándole abriendo el archivo "DynamicXTool.exe", al hacerlo se te abrirá una consola diciéndote que escribir en cada momento. Iniciara preguntandote por los paths del ROM, carpeta de Pixi, UberasmTool o GPS (estos ultimos 3 son optativos) y luego te preguntara por los features que quieres instalar, pon "y" o "yes" para habilitar cada feature y "n" o "no para deshabilitar ese feature.
Advertencia: Los features como Player Features y Status Bar Optimization, pueden tener incompatibilidades con otros recursos, así que debes tener cuidado al instalarlos. Tener cuidado con que features instalan.
Usando el Tool Desde Consola
Debes llamar el comando:
DynamicXTool -use-settings
El ROM se instalara con los settings default si nunca se ha hecho una instalación previa, si se ha hecho una instalación previa, entonces se usaran los settings usados en esa instalación.
Settings
En caso de querer cambiar los settings manualmente debes abrir el archivo settings.json que se vera así:
{ "InputROMPath": "", "OutputROMPath": "", "PixiPath": "", "UberasmToolPath": "", "GPSPath": "", "GraphicChange": true, "PaletteChange": true, "PaletteEffects": true, "DynamicPoses": true, "DrawingSystem": true, "ControllerOptimization": true, "FixedColorOptimization": true, "StatusBarOptimization": false, "ScrollingOptimization": true, "PlayerFeatures": false }
Debes cambiar los parámetros según los settings que desees.
Mejoras en Comparación a otros sistemas
Dynamic X VS DSX
- Dynamic X contiene muchos features que DSX no posee. El DSX solo posee soporte para sprites dinámicos. Por favor ver capitulo Funcionalidades.
- DSX permite máximo 4 sprites dinámicos de 32x32, 2 de 48x48 o 1 de 64x64. Dynamic X tiene menos limitaciones en el número de sprites, primero por que todos los sprites comparten poses, por lo tanto, si hay 2 sprites iguales es muy probable que puedas usar todos los que quieras en pantalla sin problemas, segundo puedes decirle al Dynamic X que espacio dinámico usar y dependiendo de ese espacio tienes más o menos limite para sprites dinámicos, de hecho, no existe un limite para sprites dinámicos como tal debido a que si un sprite no puede cargar una pose en la vram, usa la ultima pose que logro cargar, por lo tanto, en el peor de los casos el sprite quedaría con su pose congelada por un momento hasta que sea capaz de cargar una nueva pose.
- DSX requiere copiar una rutina a todos los sprites que usan su sistema, Dynamic X es solo llamar una rutina de la API, en 3 lineas de codigo puedes subir una pose a la VRAM y dibujar esa pose, eso hace al Dynamic X mucho más eficiente en ROM.
- DSX no tiene sistema de dibujado, el sprite debe tener su propia rutina gráfica, lo que no solo hace que cada pose dinámica sea solo utilizable dentro del contexto del sprite, sino que gasta mucha más ROM al tener que hacer esa rutina gráfica. Dynamic X por otro lado, permite cargar cualquier pose dinámica y dibujarla desde cualquier código ASM, lo que le da mucha más flexibilidad de uso y además al tener un sistema centralizado de dibujo, se ahorra mucho espacio en ROM.
- El DSX permite como máximo, cargar poses dinámicas de 64x64 (16 tiles de 16x16), Dynamic X no tiene un limite, si puedes optimizar el NMI handler podrías teóricamente hacer poses de hasta 96x96 (32~36 tiles de 16x16), aunque sin optimizaciones fuertes y solo desactivando las exanimations vanilla, podrías conseguir un sprite 80x80 (24~25 tiles de 16x16).
- Los gráficos del Dynamic X, son optimizados, esto significa que a pesar de no estar comprimidos con algoritmos como LZ, si usan la menor cantidad de tiles de 16x16 y 8x8 posibles, por lo tanto, esto permite utilizar sprites más grandes y optimizar las transferencias a la VRAM, lo que aumenta su capacidad de tener más poses dinámicas cargadas en la VRAM. El DSX por su parte, los gráficos no tienen ningún tipo de optimización y suelen malgastar mucho espacio con zonas en blanco.
- El DSX usa un buffer que luego es enviado a la VRAM, esto es un problema debido a que generar ese buffer es muy lento y requiere muchos ciclos, además el DSX debe generar este buffer en cada frame, por lo que un sprite dinámico hecho para DSX suele ser muy lento y utilizar muchos recursos, incluso utilizando SA-1 podrías tener problemas de slowdown si utilizas sprites dinámicos y algún efecto de hdma que sea complejo como un parallax o un wave. El Dynamic X no utiliza un buffer, si no que usa cola de transferencias que se carga directamente a la VRAM sin buffers intermedios, no solo eso, sino que cada pose es cargada solo cuando es necesario, por lo tanto, la carga no se hace en cada frame, sino cuando es necesario, además en ciertos sprites puedes sincronizar la animación para que todos usen exactamente la misma pose o una pose que ya esta cargada en la VRAM, esto reduce considerablemente el slowdown.
Dynamic X VS Dynamic Z V3.7
Formatos
Dynamic Info
Los archivos con extensión ".dynamicinfo" se utilizan para insertar gráficos de poses, paletas y otros recursos en el ROM. Además incluyen la información necesaria para que las poses sean cargadas correctamente en la VRAM.
El formato de estos archivos es el siguiente:
PosesGraphics: ... Palettes: ... Resources: ... PosesChunksSizes: ...
- PosesGraphics: Debajo de este label va cada archivo de gráficos utilizado para cargar poses dinámicas. Ejemplo:
PosesGraphics: DKCKlaptrap.bin
- Palettes: Debajo de este label va cada archivo de paletas de colores utilizado para las poses dinámicas. Ejemplo:
Palettes: DKCKlaptrapPal1.bin DKCKlaptrapPal2.bin DKCKlaptrapPal3.bin DKCKlaptrapPal4.bin DKCKlaptrapPal5.bin
- Resources: Debajo de este label va cada archivo extra que se utilice como recurso y que se desee insertar en el ROM. Ejemplo:
Resources: Geno.bin GenoPal.bin FireGenoPal.bin GenoPalPlayer2.bin FireGenoPalPlayer2.bin
- PosesSizes: Debajo de este archivo van 2 líneas por cada pose, la primera linea es un label que describe la pose y la segunda linea son 2 valores, cada uno de estos valores indica cuantos tiles de 8x8 se usan en cada chunk, cada pose dinámica tiene 2 chunks de data generalmente (excepto algunas excepciones que pueden requerir solo 1 chunk), el chunk de arriba y el chunk de abajo. El chunk de arriba son todos los tiles de 8x8 que están antes de la ultima linea de 8 pixeles de alto, mientras que el chunk de abajo es la ultima linea. En el siguiente ejemplo se pueden ver 3 imagenes, la de la izquierda es como deberia verse la imagen ensamblada, la segunda es como se veria en la VRAM y la tercera es como estaria guardado en el archivo binario, tambien mostraria como son los poses sizes de esa pose, que en este caso serian 8 tiles del chunk de arriba y 8 tiles del chunk de abajo:
PosesChunksSizes: Frame0_PoseChunksSizes: db $08,$08
Nota: Para poses cuyo número de tiles de 8x8 sea divisible por 32, se puede usar solo el chunk de arriba que tiene todos los tiles y el chunk de abajo quedaria en 0.
Draw Info
Los archivos con extensión ".drawinfo", tienen la información necesaria para dibujar poses, estas poses pueden ser dinámicas o poses estáticas. El Dynamic X utiliza estos archivos para generar rutinas gráficas optimizadas para cada pose, el tool detecta si es necesaria o no una de las tablas, elimina data redundante o que no aporta, encasilla cada pose en un grupo que comparte características similares y luego inserta una rutina gráfica por cada grupo de poses que comparten características similares. El formato del archivo es el siguiente:
Dynamic: ... Tiles: ... XDisplacements: ... YDisplacements: ... Sizes: ... Properties: ...
- Dynamic: Si es true es dinámica, si es false es estatica, ejemplo:
Dynamic: true
- Tiles: Es una tabla que indica que tiles utiliza cada pose, en el caso de las poses dinámicas debe considerarse que el tile de más arriba a la izquierda es el tile
$00
, esta tabla contiene 2 líneas por cada pose, la primera línea esPoseName_Tiles:
y la segunda línea seria cada uno de los tiles utilizado por la pose. Esta tabla es optativa y en caso de que no este, utilizara el valor$00
para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32:
Tiles: Pose32x32_Tiles: db $00,$02,$04,$06
- XDisplacements: Es una tabla que indica el desplazamiento horizontal de cada tile con respecto a la posición de la pose y contiene 2 líneas por cada pose, la primera línea es
PoseName_XDisp:
y la segunda línea es un valor por cada tile de la pose indicando cuanto debe moverse horizontalmente cada tile con respecto a la posición de la pose, adicionalmente se pueden añadir 2 líneas más por cada pose para cuando la pose es volteada horizontalmente, el formato es el mismo de las 2 líneas anteriores solo que la primera línea esPoseName_XDispFlipX:
. Esta tabla es optativa y en caso de no existir, utilizara el valor$00
para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32 y permitiendo volteo horizontal:
XDisplacements: Pose32x32_XDisp: db $00,$10,$00,$10 Pose32x32_XDispFlipX: db $10,$00,$10,$00
- YDisplacements: Es una tabla que indica el desplazamiento vertical de cada tile con respecto a la posición de la pose y contiene 2 líneas por cada pose, la primera línea es
PoseName_YDisp:
y la segunda línea es un valor por cada tile de la pose indicando cuanto debe moverse verticalmente cada tile con respecto a la posición de la pose, adicionalmente se pueden añadir 2 líneas más por cada pose para cuando la pose es volteada verticalmente, el formato es el mismo de las 2 líneas anteriores solo que la primera línea esPoseName_YDispFlipY:
. Esta tabla es optativa y en caso de no existir, utilizara el valor$00
para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32 y permitiendo volteo vertical:
YDisplacements: Pose32x32_YDisp: db $00,$00,$10,$10 Pose32x32_YDispFlipY: db $10,$10,$00,$00
- Sizes: Es una tabla que indica el tamaño de cada uno de los tiles que se utiliza, cada valor es
$00
para tiles de 8x8 y$02
para tiles de 16x16. Contiene 2 líneas por cada pose, la primera línea esPoseName_Sizes:
y la segunda línea es un valor por cada tile de la pose indicando el tamaño de cada tile. Esta tabla es optativa y en caso de no existir, utilizara el valor$02
para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32:
Sizes: Pose32x32_Sizes: db $02,$02,$02,$02
- Properties: Es una tabla que indica las propiedades de cada tile, las propiedades siguen el formato YXCCPPPT, donde X es si el tile es volteado horizontalmente, Y es si el tile es volteado verticalmente, CC es la prioridad con respecto al layer 1 y layer 2, donde 00 es la prioridad más baja y 11 es la más alta, CCC es la paleta de colores usada por el tile y T es 1 para usar SP3/SP4 y 0 para SP1/SP2. Contiene 2 líneas por cada pose, la primera línea es
PoseName_Sizes:
y la segunda línea es un valor por cada tile de la pose indicando la propiedad de cada tile. Esta tabla es optativa y en caso de no existir, utilizara el valor que se entregue en el!PropParam
para los tiles de la pose. El siguiente ejemplo dibuja 4 tiles formando una pose de 32x32:
Properties: Pose32x32_Properties: db $20,$20,$20,$20
Palette Effect
Los archivos con extensión ".paleffect" son archivos json que se utilizan para múltiples efectos de paletas de colores, tanto globales como normales, estos archivos pueden ser creados utilizando el tool "Palette Effect Creator" que es incluido al Dynamic X. El formato de estos archivos es el siguiente:
{ "Name": ..., "Effects": [...] }
- Name: Es el nombre del conjunto de efectos de paletas de colores. Ejemplo:
"Name": "DecreaseSaturation",
- Effects: Es una lista con cada uno de los efectos de paletas de colores, estos tienen 7 parámetros, los primeros 3 son Channel1, Channel2 y Channel3 que son valores entre 0 y 31 que indican el valor de cada canal, en el caso de un efecto RGB, el Channel1 es R, el Channel2 es G y el channel3 es B, en el caso de un efecto HSL, el Channel1 es H, el Channel2 es S y el Channel3 es L, luego vienen 3 valores más, el Ratio1, Ratio2 y Ratio3, cada uno de estos es un número entre 0 y 31 indicando cuanto afecta cada Channel a los colores de la paleta de colores, donde 0 es que afecta en un 0% y 31 es que afecta en un 100%, por ultimo Channels es para indicar si es un efecto RGB o HSL, 0 es RGB y 1 es HSL. El sguiente ejemplo muestra 2 efectos HSL que disminuyen la saturación:
"Effects": [ { "Channel1": 0, "Channel2": 0, "Channel3": 0, "Ratio1": 0, "Ratio2": 30, "Ratio3": 0, "Channels": 1 }, { "Channel1": 0, "Channel2": 0, "Channel3": 0, "Ratio1": 0, "Ratio2": 31, "Ratio3": 0, "Channels": 1 } ]
Palette Effect Creator
Puedes encontrar el tool en el sitio web oficial de Dynamic X:
Modo de Uso
Carga Dinámica de Poses
Cambiar Configuración de Espacio para Poses Dinámicas
Dibujar Poses
Carga y Dibujo de Poses en Sprites
Los sprites (Sprites normales, clusters y extended) poseen rutinas especiales que se insertan en las Shared Routines de Pixi al momento de instalar el Dynamic X, estas rutinas simplifican considerablemente el trabajar con poses dinámicas y con el sistema de dibujo del Dinamic X.
Upload
La primera rutina es Upload, esta rutina carga en el espacio destinado para poses Dinámicas, la pose que deseas. Posee 2 versiones el Upload normal y el UploadWithoutPoseOffset
-
Upload
- Versiones: %DXNormalUpload(), %DXClusterUpload(), %DXExtendedUpload().
-
Input:
-
A: ID de la pose base (16 bits). Se puede usar el define autogenerado por Dynamic X que es
!DynamicPoseID<Nombre del Dynamic Info>000
. Ejemplo:!DynamicPoseIDDKCKlaptrap000
. -
!PoseIndex,x: La pose dentro del contexto que se desea cargar. Se calcula la pose como
A + !PoseIndex,x
. Por ejemplo si deseamos la pose 5 de Klaptrap en A se pondria!DynamicPoseIDDKCKlaptrap000
y en!PoseIndex,x
pondriamos el valor$05
.
-
A: ID de la pose base (16 bits). Se puede usar el define autogenerado por Dynamic X que es
-
Output:
-
Carry: Si despues de la rutina hay un Carry Set, puede significar 3 cosas:
- La pose fue cargada con éxito.
- La pose ya estaba cargada previamente y se esta reutilizando.
- La pose no fue cargada y no fue encontrada, pero en un ciclo anterior si se cargo una pose en la VRAM y se puede usar.
Si el Carry es un Carry Clear, la pose no pudo ser cargada y previamente no se cargo ninguna pose, en este caso lo recomendable seria despawnear el sprite, excepto si es un Boss o un sprite que debe ser persistente en el nivel.
-
!LastPoseIndex,x: Tendrá el valor de la ultima pose que fue cargada a la VRAM. Al momento de dibujar o de hacer una rutina de interacción que tenga cajas de colisión dependientes de la pose, se debería utilizar esta tabla. Si es
$FF
entonces nunca se ha cargado una pose previamente. -
!LastPoseHashIndex,x: Es de uso interno, pero básicamente contendrá el valor del ID que indexa la tabla hash de poses de la ultima pose que fue cargada. Si es
$FF
entonces nunca se ha cargado una pose previamente. Si es$FF
entonces nunca se ha cargado una pose previamente. -
!LastFlip,x: Es el valor de
!GlobalFlip,x XOR !LocalFlip,x
que tenia la ultima pose que fue cargada. Al momento de dibujar o de hacer una rutina de interacción que tenga cajas de colisión dependientes de la pose, se debería utilizar esta tabla. Si es$FF
entonces nunca se ha cargado una pose previamente. -
$04: Tendra el valor
$00
si el primer tile de la pose esta cargado en SP1 o SP2, o$01
si el primer tile de la pose fue cargado en SP3 o SP4. - $08: Tiene el Offset del primer Tile que se cargo en la pose.
-
Carry: Si despues de la rutina hay un Carry Set, puede significar 3 cosas:
-
UploadWithoutPoseOffset
- Versiones: %DXNormalUploadWithoutPoseOffset(), %DXClusterUploadWithoutPoseOffset(), %DXExtendedUploadWithoutPoseOffset().
-
Input:
-
A: ID de la pose deseada (16 bits). Puedes utilizar los defines autogenerados por Dynamic X para la pose que inician con
!DynamicPoseID
.
-
A: ID de la pose deseada (16 bits). Puedes utilizar los defines autogenerados por Dynamic X para la pose que inician con
- Outputs: Los mismos de Upload.
Draw
La segunda rutina es Draw, esta rutina se encarga de dibujar una pose, puede recibir ciertos parámetros para cambiar las propiedades, la posición o la prioridad de la pose. Tiene 2 versiones distintas Draw y DrawWithOffset.
-
Draw
- Versiones: %DXNormalDraw(), %DXClusterDraw(), %DXExtendedDraw()
-
Inputs:
-
DrawWithOffset
- Versiones: %DXNormalDrawWithOffset(), %DXClusterDrawWithOffset(), %DXExtendedDrawWithOffset()