Demo de desarrollo para NES - HEOHdemo

La historia de los festivales de arte por computadora, también conocida como demopati, ha existido durante un cuarto de siglo en nuestro país. Gente de todo el país se está reuniendo para mostrar sus ejercicios para extraer lo imposible de las computadoras antiguas o modernas y cantidades de código ultrapequeñas. En el primer período de cinco años, CAFe (de repente, Computer Art Festival ), que se celebró en Kazán de 1999 a 2003, se convirtió en una de las principales demopatías del país. Más tarde, desapareció de los radares durante mucho tiempo, dando la palma a las construcciones más famosas de Chaos y DiHalt , y este año su regreso fue bastante triunfante, si no por la escala del evento, luego por la cantidad de varias obras, que duraron hasta las seis de la mañana. Entre ellos estaba el mío, cuya creación se discutirá en este artículo.


En el demoscene, soy más comprensivo que un participante activo. Mis intereses principales están en el desarrollo de juegos retro y software de sonido. Anteriormente, solo hice una demostración condicionalmente completa para un teléfono rojo , que desde entonces se ha convertido en un meme de la escena, y alrededor de una docena de pequeñas introducciones para diferentes plataformas. Los organizadores de CAFe , que comenzaron la agitación personal de los autores de antemano, primero de forma remota, a través de amigos mutuos y luego en reuniones personales, finalmente me motivaron a crear mi primer trabajo verdaderamente completo en la categoría de demostración de larga duración. Como sucedió, en otra plataforma no es la más popular: la consola de juegos NES / Famicom , conocida por la mayoría con el nombre de Dandy.

Planificacion


Inicialmente, iba a hacer una demostración largamente concebida para otra plataforma de 8 bits más popular. Pero para su implementación, era necesario llevar a cabo una cantidad significativa de trabajo de investigación, es decir, no se entendía ni el momento, ni la viabilidad fundamental de la idea, ni la calidad del posible resultado. Por lo tanto, se tomaron acciones específicas muy lentamente. Los plazos comenzaron a agotarse significativamente, y quedó claro que si quiero mantener la promesa de participación, es urgente elegir otro proyecto de implementación más predecible. Después de pensar en la segunda idea, para la categoría Wild , que también requería experimentación, decidí volver a los antiguos espacios en blanco de demostración para NES , realizados hace tres años, luego para el Multimatograph . Como resultado, ellos mismos no fueron realmente utilizados, pero finalmente se determinó la dirección del trabajo.

El plan para hacer un trabajo específico para NES finalmente se aprobó a principios de octubre, hasta que faltaban unas tres semanas para CAFe . La carpeta del proyecto se creó el 5 de octubre, pero algunos movimientos tuvieron lugar antes de eso.

La primera pregunta que debía resolverse era cuántos efectos (escenas) se necesitaban para que la duración de la demostración fuera suficiente para reclamar una forma grande, en lugar de una simple introducción. También se requería entender cuál era esta duración suficiente.
Para esto, entre otras cosas, se revisaron los principales trabajos actuales para la plataforma seleccionada en Pouet , y se analizaron los dos mejores: High Hopes y NESPECCY . La última, que es una invitación a la misma demopati, se lanzó en diciembre de 2018, y hasta ese momento no me había llamado la atención. Al principio, incluso llegó a la motivación, ya que inicialmente asumí un nivel más fácil para mi trabajo futuro.

Según los resultados del análisis, resultó que en High Hopes hay alrededor de seis efectos y una duración de 2:45, y en NESPECCY alrededor de 11 efectos y una duración de 3:45. Eso es un promedio de aproximadamente 25 segundos por efecto. Sugerí que, en promedio, 10-15 efectos serán suficientes, en base a la suposición de que solo 3-5 de ellos serán relativamente complicados técnicamente, y el resto pueden ser simples pero bonitos rellenos. Para no retrasar la visualización de escenas simples, en promedio resultará aproximadamente 15 segundos por efecto, con la duración total de la demostración en aproximadamente los mismos dos o tres minutos.

Esto fue seguido por un cálculo de cuánto tiempo puede gastarse en crear cada efecto. Resultó uno y medio o dos días, sin contar los muchos otros trabajos necesarios, como música, gráficos, algún tipo de idea, y simplemente preparando una base técnica que combina los efectos. Tal calendario no parecía muy realista, pero decidí hacer tantos efectos como pudiera, tratando de encajar en dos días para cada uno.

Por lo tanto, se determinó la tarea prioritaria: poder hacer a tiempo al menos algo adecuado para la participación en la competencia, así como el modo de desarrollo al estilo de "no hay tiempo para explicar". Esto también descartó el diario de desarrollo, y ahora tienes que recuperar eventos de la memoria, tratando de no mentir demasiado.

La tarea de hacer el trabajo, reclamando el primer lugar, no se planteó. Lo principal no es la victoria, sino la participación y todo eso, y en general la victoria principal está por encima de uno mismo. No hice ningún pronóstico especial basado en los resultados de la competencia por la impopularidad de la categoría seleccionada, esperando que en el peor (mejor) caso de participación en la competencia de varias obras bastante fuertes, la mía se convierta en rellenos compuestos, que también son necesarios e importantes, y si no hay obras, lo haré nuevamente un ganador entre sí, como ya ha sucedido en otras disciplinas. Por supuesto, quería ganar una pelea decente, pero yo mismo califiqué mi trabajo por debajo de lo que la audiencia finalmente estimó.

Código


Después de que se establecieron los plazos, quedó claro que para tener tiempo de plantear dicho proyecto, era necesario vincularlo con un perfeccionismo inapropiado y no tratar de crear el código de demostración más tecnológico o compacto. Cuanto más simple y rápido, mejor, mientras se mantiene un efecto externo suficiente.

Se decidió elegir una configuración bastante potente e incluso redundante: un mapeador MMC3 con 256 kilobytes de código ROM y 256 kilobytes de ROM gráfica, y tratar de no preocuparse de que todo su potencial permanezca sin explotar. Esta configuración no es la más avanzada de las existentes y aún más posible, se ha utilizado ampliamente en juegos comerciales, comenzando con Super Mario Bros. 3 (1988), pero anteriormente los autores de la demostración para NES se limitaban a mapeadores más simples y menos memoria. Como resultado, se utilizó el 80% del volumen del código ROM y un poco menos de dos tercios del volumen de los gráficos ROM. La cantidad excesiva de memoria nos permitió no perder tiempo extra resolviendo el problema de compresión de datos, aunque no podría prescindir de él.

El método de desarrollo también era obvio, principalmente en C, con insertos de ensamblador según sea necesario, principalmente copiando a la memoria de video, manejadores de interrupciones y un reproductor de música. Durante mucho tiempo y con éxito he estado utilizando este enfoque en plataformas retro. Ahorra mucho tiempo de desarrollo, ya que la creación de prototipos de código se puede hacer localmente: primero impleméntelo en C e inmediatamente obtenga un resultado que funcione en NES , y luego, si no funciona lo suficientemente rápido, vuelva a escribirlo en partes para ensamblar de acuerdo con una plantilla ya preparada, hasta Se ha alcanzado la velocidad requerida.



Uno de los principales problemas esperados, que, sin embargo, en la práctica no causó muchos problemas, fue la cantidad de RAM principal: en NES es de solo 2 kilobytes, y en mi trabajo decidí hacerlo sin expandirlo, aunque el mapeador básicamente permitió este movimiento. La memoria en los sistemas basados ​​en el procesador 6502, en vista de su capacidad total de ocho bits, a menudo se considera en páginas de 256 bytes, y en ellos la distribución de RAM resultó de la siguiente manera:

  • Una página para variables "rápidas";
  • Una página para la pila y paleta de hardware (no se usa una parte significativa de la pila);
  • Una página para el búfer de la lista de sprites (las características de la arquitectura del controlador de video lo requieren);
  • Una página para una lista de actualizaciones de memoria de video;
  • Una página para obtener una lista de parámetros para efectos ráster.

Los dos últimos se declaran en el programa en forma de conjuntos de caracteres ordinarios sin signo de 256 bytes y en algunos lugares también se reutilizan para otros fines. Las tres páginas restantes se dan bajo la pila del programa cc65 , es decir, bajo las variables globales y locales del programa C.

Cabe señalar que la asignación dinámica de memoria (malloc / free) en tales plataformas prácticamente no se usa, se requería una solución estática. Al principio, me adhirí al método de usar tantas variables locales como sea posible, lo que me permitió reutilizar automáticamente la memoria de la pila de software para ellos. Pero las variables locales funcionan mucho más lentamente, y como resultado, el volumen disponible para las variables globales comenzó a faltar, y era incómodo escribir código de esta manera, usando repetidamente variables del mismo nombre. Luego apliqué una solución no utilizada anteriormente: un anuncio en la configuración del enlazador de varios segmentos de RAM ubicados físicamente en las mismas direcciones. Los grupos de variables utilizadas dentro del mismo efecto se colocaron utilizando directivas del compilador en estos segmentos, lo que permite la reutilización de la misma memoria.

Otro problema, la distribución del código del programa C por los bancos de memoria de código ( NES usa el direccionamiento de página para memoria extendida), ya lo resolví en otros proyectos y no causó problemas. El código para colocar en las páginas está limitado a 16 kilobytes (el tamaño de la ventana de memoria conmutable) a una sección funcionalmente completada, y se llama por el método de superposición: la página deseada se conecta, el código se procesa, la ejecución vuelve a la página principal y el acceso a la memoria entre páginas es imposible. Las funciones se asignan a los bancos manualmente, a través de las directivas del compilador. El código requerido en todas las partes del programa, como un reproductor de música, salida de sprites y controladores de interrupciones, se encuentra en la ventana de memoria superior no conmutable, también de 16 kilobytes de tamaño.

Al trabajar en el último efecto, el corredor con Mario, me encontré con un entretenido mensaje de error de compilación: desbordamiento de etiqueta local . Según tengo entendido, el compilador tiene un límite interno en la cantidad de etiquetas locales generadas (aparentemente 65536) dentro de un módulo de objeto, pero utilicé un módulo común para simplificar la administración de la memoria compartida. Una de las posibles soluciones fue dividir el código en varios módulos, y ya planeé aplicarlo, sin embargo, después de mover una matriz de constantes de la fuente a C en la parte del ensamblador ( incbin con una etiqueta externa), el problema se resolvió por sí mismo, el límite dejó de excederse e incluso después de agregar un par de cientos de líneas de código ya no aparecía un mensaje de error.

Desarrollo


En la elección de los efectos, había un plan para limitarnos a simples, pero siempre suaves, trabajando a la velocidad de visualización completa (60 cuadros por segundo). Los efectos de demostración tradicionales, como los rotadores de plasma y zoom, no se consideraron inicialmente, ya que no encajan bien en la arquitectura del decodificador, que tiene restricciones significativas en el acceso a la memoria de video; esto se vería pésimo en comparación con las plataformas donde dichos efectos se implementan repetidamente en todo su esplendor.

Primero, quería hacer la mayor parte de los efectos de acuerdo con un plan de tres años, basado en manipulaciones línea por línea con el ráster visualizado, cambiando el desplazamiento vertical y horizontal de cada línea, así como los bancos del gráfico visualizado, a medida que el haz pasa a través del ráster. Tal enfoque podría funcionar sobre la base de un bloque de código común, ahorrando tiempo de desarrollo, pero los efectos resultarían ser bastante uniformes, y también bastante tradicionales, que se encuentran en muchos otros trabajos. Además, hubo dificultades para depurar este bloque de código general y, como resultado, la demostración incluyó solo un efecto de este tipo, un cartucho rotativo.

Mientras abordaba un par de efectos basados ​​en ideas antiguas, uno de los cuales eventualmente se convirtió en el efecto Kirby, y el segundo no entró en la demostración, comencé a escribir un documento de texto donde escribí todas las ideas que se me ocurrieron, tanto para efectos individuales como para el concepto general. Esta lista incluía más de 40 efectos, mientras que en el trabajo final se implementaron menos de 15. Al mismo tiempo, la mayoría de los efectos son animaciones de un tipo u otro, aunque cada una de sus variantes es bastante única y utiliza varios trucos para garantizar un consumo de memoria aceptable y la operación suave requerida. . También sucedió involuntariamente que el tipo predominante de efectos es la rotación de algo. En principio, esta es una buena coincidencia, ya que surgió una especie de unidad conceptual.

Una introducción con un elefante fue concebida y realizada, como una broma sobre el tema de mi trabajo anterior, luego un efecto con rayas de colores e interferencia. Sin pensarlo mucho, el título de trabajo, HEOHdemo , fue elegido como continuación de la broma de la introducción (HE IS NOT HE). En cuanto a la realización de la escena con la presentación del nombre, se aprobó como final, porque no había más ideas exitosas para ese momento, y no había tiempo para pensar en ellas.

Una decisión espontánea con la demostración del nombre provocó el concepto final de todo el trabajo, que finalmente tomó forma diez días antes de la fecha límite. Implicaba el uso de videojuegos reconocibles y material de cultura pop, como personajes, logotipos, escenas de juegos, pero modificado de tal manera que los originales fueran un poco diferentes (como "no ellos"). También se decidió difundir el humor de las escenas iniciales y finales a toda la demostración, compensando así el nivel técnico no muy alto, que está bastante en el espíritu de la era citada (mediados de los 90), y atrae a un público más amplio; después de todo, las consolas de juegos antiguas tienen su propia, no se cruza con el demoscene y no es muy ilustrado en tecnología, pero tiene una audiencia muy amplia. Casi al mismo tiempo, se decidió utilizar la demostración inherente de los 90 dividida en escenas independientes separadas, ya que son más fáciles de hacer en el tiempo disponible, y esto posteriormente ayudó mucho con la parte de música y la sincronización de los efectos con ella.

Las ideas de escenas con Vid, un logotipo giratorio y en parte con Mario en el corredor también surgieron naturalmente durante el trabajo. Se hicieron fuera de turno, como una especie de dilación, hasta que se pegaron los principales efectos planificados.

Asamblea


Inicialmente, estaba claro que el tiempo más largo en el tiempo tomaría parte con una introducción, título, saludos y créditos finales. El trabajo en ellos se llevó a cabo en primer lugar, por lo que en algún momento resultó que la demostración ya tiene un comienzo y un final completos (lo mismo que en el lanzamiento final), pero casi no hay un punto medio para el que solo uno estaba más o menos listo efecto Los plazos estaban llegando a su fin. El trabajo en el proyecto se convirtió en una maratón de una hora de duración, ocupando todo el tiempo libre y no libre. Los efectos restantes en los planes se ordenaron por complejidad, todas las ideas se simplificaron lo más posible. Se hicieron invasores espaciales, se derrotaron los problemas con un cartucho giratorio y se completó una torre fácil de implementar con un crujido (experimentó con la apariencia). Cuando los efectos estuvieron listos, se determinó la secuencia de su visualización.

Cada poco tardó tres veces más tiempo de lo que parecía al principio, y unos días antes de la fecha límite, cuando todavía no había la mitad de los efectos o la música, había una fuerte sensación de que no funcionaría. Se consideró el Plan B, para completar y exponer el trabajo ya en otra demopati, o fuera de ella. Pero luego se tomó una decisión más efectiva: recopilar y completar con urgencia todo lo que ya está allí, en al menos una apariencia de un producto listo para su lanzamiento, incluso completamente estúpido, para escribir algo de música para esto, y si aún queda tiempo después de eso, Intenta agregar más efectos. Entre esas escenas agregadas en el último momento estaban Pakman y el corredor, ambos en la versión más simplificada en comparación con las ideas originales.

Este método de ensamblaje condujo a una notable incoherencia de efectos en el medio de la demostración y un cambio completo de música entre muchas escenas. Sin embargo, ayudó a ahorrar mucho tiempo y, de hecho, el trabajo estaba completamente listo para su lanzamiento un día antes de la fecha límite. Este tiempo extra se dedicó a finalizar varias pequeñeces en todas las partes y en la música. En particular, fue en este momento que los invasores y el sapo adquirieron su apariencia alternativa.

Depuración


Por falta de capacidades de depuración en hardware real, así como en el hardware en sí, la demostración se depuró exclusivamente en emuladores. El trabajo principal fue en el emulador FCEUX . No es muy preciso, pero tiene un buen depurador y se inicia muy rápidamente, lo cual es importante con el método de desarrollo de "agregar un par de líneas, ejecutar, verificar". Los efectos críticos de tiempo también se depuraron en Mesen , punes y Nestopia , mucho más precisos pero menos convenientes.

Dado que el formato de demostración en sí implica el deseo de obtener de la plataforma lo que nadie hizo anteriormente en él, prueba la precisión de los emuladores para la fuerza, incluso mostrando su desacuerdo sobre varios casos extremos. Después de depurar el efecto en un emulador, puede obtener artefactos en otros emuladores. Debido a esto, y también debido a las características de la arquitectura NES , muchos efectos vinculados a tiempos precisos tuvieron que ser depurados repetidamente muchas veces. Como resultado, configuré la demostración para el trabajo limpio en el popular emulador FCEUX , con el que se envió al concurso, y para el trabajo normal en todos los demás emuladores.

De los errores interesantes encontrados durante la depuración, había un problema en la escena con un logotipo giratorio, que se manifestaba exclusivamente en el emulador Mesen . inspired by, , . , Mesen . .

NTSC - , PAL — , . , PAL -, . , 17% .

NES , Famicom AV , Pegasus ( Dendy Classic 2 , ). , , , , . , , MMC3 Flash -, MMC3 . Pegasus , — . , — — .

, , . , , . Flash -.

Musica


« » «». . ' , . , , , , . , . .

NES , , , -. , , , , , . , .

Reaper MIDI-, , FamiTracker . MIDI-, Reaper, FamiTracker .



FamiTracker NES , , , — , . , . , «» FamiTracker ' NSF - . , , NES .

. . FamiTracker Zxx , .



. , . « » , , .


, , . .

, — Graphics Gale , (10). , . NES Screen Tool .



, , , . , , .

8 32 , PC. . MMC3, ( ), , . , .




El primer efecto completo que se escribió para la demostración. De hecho, consta de dos partes: primero se muestra un temporizador que muestra el tiempo de demostración actual casi real, luego el efecto cambia a una animación de bandas crecientes.

, , . 12x16 , 8x8, — . — 00 99, — . . , .



, , MMC3, , .

, 32 . 238 , 7 . , , , 53. , PC, , .


Titulo


, , .

. . . Blender . , , NES Screen Tool – 82 . , .



, . , , . , , . , .



MMC3 , .


, , , Gale . , , .



. .

, . , , .


Debido a la falta de efectos y al tiempo para desarrollarlos, decidí reutilizar una pequeña introducción escrita hace un par de años, en la que las letras volaban por el mismo camino alrededor de un logotipo estático. Recientemente, nuevamente me interesé en el prefijo N64 , que pasé por alto a fines de los 90, y en el proceso de trabajar en otros efectos, surgió una idea espontánea con la animación de la rotación del famoso logotipo, que parecía muy simple de implementar; estos dos pensamientos se unieron, pero la implementación tomó mucho más tiempo de lo esperado.

La principal complejidad técnica de la escena es la reducción de la cantidad de memoria requerida para una animación tan suave y grande. Si almacena sus cuadros sin compresión, un cuadro ocuparía un conjunto de 4 kilobytes (ya que dos cuadros no encajarían en 256 mosaicos), y tomaría 256 kilobytes de ROM gráfica, es decir, todo el volumen utilizado en la demostración. Para resolver este problema, se aplicaron tres trucos a la vez: animación de rotación de solo 90 grados (64 cuadros), después de lo cual se intercambian dos colores de la cara; conversión de gráficos con pérdida para colocar grupos de cuatro cuadros en conjuntos de 256 mosaicos; así como actualizar la memoria de video en la parte visible del ráster. Por lo tanto, la animación tomó cuatro veces menos espacio.

El modelo de letra y la animación de rotación se realizan en Blender . Durante su espejo su idea vino que se corresponde con el concepto de demostración, y que era divertido - la escena está diciendo "y-y-y-y-y-y." Los cuadros de animación se agrupan, la profundidad de color se reduce a 4, y estas imágenes se convierten mediante la función de importación con pérdida en la herramienta de pantalla NES . Esta función es quizás mi arma secreta principal: si se excede el límite de mosaico durante la compresión, busca los mosaicos visuales más similares y los combina hasta que permanezca el número requerido de mosaicos. Por supuesto, esto proporciona artefactos de conversión visual y requiere un refinamiento manual posterior, pero le permite exprimir imágenes más complejas con menos trabajo en el límite.



Para la animación del logotipo, se cambian conjuntos de mosaicos y se actualiza la ventana de 14 por 14 mosaicos en el mapa de mosaicos de fondo, para lo cual se utiliza la interrupción MMC3, que se activa antes de una línea de texto. Para una línea, también debe cambiar el conjunto de gráficos a una fuente, después de lo cual hay un retraso en el código por el tiempo que se muestran las líneas de la inscripción, luego la pantalla se apaga (el color de fondo se muestra constantemente) y los datos se transfieren a la memoria de video.

Las monedas se muestran por sprites y vuelan a lo largo de un camino calculado más o menos honestamente (usando un punto fijo). El código anterior se ha modificado para que la rotación continúe, si es posible sin intersectar con el logotipo más grande, así como para que las monedas aparezcan y desaparezcan gradualmente en los momentos correctos. Van más allá de los gráficos del logotipo utilizando la bandera de prioridad que tiene cada sprite.

Cartucho giratorio


La implementación del efecto es muy simple en palabras, pero requirió una larga depuración. El controlador de interrupciones lanza un efecto de trama en la línea deseada (para dejar tiempo para el hilo principal). A continuación, el código con tiempos seleccionados con mucha precisión se ejecuta para establecer el desplazamiento vertical píxel por píxel del mapa de mosaico visualizado para cada línea de la pantalla. Esto requiere un esquema muy complicado de escribir en registros PPU , y algunos de ellos deben caer exactamente en un lugar determinado de la línea. En la versión NTSC del decodificador, la velocidad del reloj del procesador y la tasa de repetición de píxeles no son múltiples, y el tiempo de ejecución del código puede variar ligeramente dependiendo de varios factores, por lo que los tiempos de cada línea flotan gradualmente y requieren corrección.

La parte principal de los gráficos para esta escena se dibujó hace varios años para un intento anterior de hacer una demostración para NES , pero ahora se ha complementado con otras caras de cartuchos y un logotipo de demostración. La imagen original se apila en altura en una pantalla. Para simplificar el código de efecto, las mismas líneas se duplican varias veces en la parte posterior del cartucho.



La animación de rotación se calcula completamente por adelantado utilizando un programa de PC y ocupa una cantidad significativa de código ROM: tres bancos de 16 kilobytes cada uno, en los que para cada uno de los 256 cuadros de la animación se almacena una tabla en 176 números de las líneas de trama mostradas. Fue posible hacer un efecto en tiempo real, ya hice una demostración similar para otra plataforma, pero en este caso había suficiente memoria libre y no había tiempo extra.

Pacman


Inicialmente, se planeó una escena más compleja, pero debido a la falta total de tiempo, ingresó a la demostración en la versión más minimalista, en forma de un desglose de las escenas en el momento del cambio de música.

El principal problema era encontrar una forma de crear animaciones rápidamente. Primero, surgió la idea de usar Blender u otros programas gráficos nuevamente. Pero después de los primeros intentos y algunos cálculos, quedó claro que solo ocho fotogramas de la animación de abrir la boca desde una posición completamente cerrada a una posición completamente abierta serían suficientes, y sería mucho más fácil y rápido dibujar manualmente en Gale .

Luego, se escribió un programa para la PC, tomando una secuencia de cuadros de un ciclo completo de animación y encontrando cuadros que cambiaron entre mosaicos. Las direcciones de estos mosaicos en el mapa de mosaicos en la memoria de video se guardan como listas de longitud variable, el efecto en la demostración simplemente actualiza las secciones modificadas de estas listas. Los gráficos de todos los marcos encajan en un conjunto de mosaicos y no cambian durante el efecto.



Kirby


Este efecto fue depurado en mi vieja imagen Catrix . Había un plan para cambiar la imagen de la cara de un gato a una imagen alternativa con un gato de Cheshire a través de algún tipo de efecto visual. Cuando surgió la idea de agregar personajes del juego a la demostración, después de una breve elección, era urgente dibujar dos nuevas imágenes de pantalla completa, se decidió tomar Kirby y convertirla en una versión "Cheshire". El efecto de cambiar las imágenes en el proceso se ha simplificado a un breve parpadeo.

Los bloques de imágenes en movimiento se muestran como sprites y se imprimen en el mapa de mosaicos cuando llegan al lugar correcto. Del mismo modo, se produce la eliminación del bloque.

Torre


Siempre me gustó el efecto en el nivel final del juego Battletoads , y siempre he querido repetirlo. En la demostración, llegó a un lugar en la escena con saludos.

La parte técnica es muy simple, este es un desplazamiento vertical normal de una capa de fondo. El efecto de rotación se logra mediante la animación de los gráficos de los mosaicos, mientras que el mapa de los mosaicos permanece sin cambios. Para la animación, el modo MMC3 se usa con cuatro ventanas CHR conmutables. La primera ventana contiene mosaicos de la parte estática, mientras que las otras tres cambian a diferentes velocidades. Una de las ventanas también cambia suavemente la dirección de la animación. Como se colocan 64 mosaicos en cada ventana, y el elemento animado requiere solo 28, los gráficos de los mosaicos se duplican en cada ventana para recibir animación en la dirección opuesta.



El principal problema para realizar el efecto fue la preparación de la animación. Fue ejecutado por un programa en una PC que toma una textura de 16x16 y una tabla de velocidad para cada columna de píxeles en la entrada, y genera un bloque de 16 cuadros de animación en forma de un conjunto de 256 mosaicos (algunos de los cuales están vacíos). Los conjuntos se convierten al formato deseado en la herramienta de pantalla NES y se distribuyen a bancos de gráficos ROM con los desplazamientos deseados a través de las opciones de la directiva del ensamblador incbin .

Otra tarea importante con respecto a los saludos fue no olvidar pasarlos a todos los que quisieran. Dado que este número tiende al infinito, una escena demasiado larga se vería aburrida. Decidí limitarme solo a aquellos con los que había estado cruzando durante un año. Los nombres recogidos en un archivo de texto como les vino a la mente. Por supuesto, después de completar el trabajo, resultó que todavía se me olvidaba mencionar a mucha gente.

Corredor


Hubo un deseo de hacer algún tipo de escena con una perspectiva, como un túnel clásico. Los túneles clásicos o un verdadero rastrillo Wolfenstein 3D han desaparecido debido a la complejidad. Además, NES ya tiene varios rakasters reales, incluidas texturas, pero no todos parecen muy impresionantes debido a la velocidad extremadamente baja.

Estoy muy interesado en los gráficos pseudo-tridimensionales en los primeros juegos, y entre los desarrollos antiguos ya había un corredor de sprites con animación suave de giros, inspirado en el juego Zig Zag para el ZX Spectrum . Se decidió usarlo. Dado que el corredor abstracto en sí no es muy interesante, se inventó una trama interna de la escena con Mario y el humor del baño, que lógicamente lo completa, así como la demostración en su conjunto. La escena fue la última y, a pesar del uso de espacios en blanco, el trabajo en ella tomó más de 11 horas seguidas, sin contar el trabajo preparatorio durante la planificación.

Todos los cuadros de movimiento se rastrean manualmente en Gale. Este es el único efecto en la demostración, yendo a una velocidad por debajo de 60 cuadros por segundo, aunque puede funcionar a esa velocidad sin ningún problema. Por razones de legibilidad visual y sincronización con música mientras se tira a lo largo del corredor, la frecuencia de actualización de la pantalla se limitó a 30 fotogramas por segundo, como alternativa a la adición de fases intermedias de movimiento, para la preparación de las cuales no quedaba tiempo.

Los marcos gráficos tomaron dos juegos de fichas. En los momentos necesarios de la animación, se actualiza la capa de fondo, se conecta el conjunto de gráficos deseado y se colocan dos colores en dos paletas (para la mitad superior e inferior de la pantalla), ya que al girar 90 grados los colores de las paredes cambian de lugar.

Las tarjetas de mosaico de animación se copian primero a la RAM mediante un código en un banco fijo desde uno de los dos bancos inferiores de la ROM. Durante la visualización del ráster inmediatamente debajo de la ventana visualizada del efecto, el renderizado se desactiva y los datos se transfieren de la RAM a la memoria de video. Desactivar el render también sirve como el límite inferior del recorte visual para el sprite de Mario.

Subtítulos


Esta escena fue una de las primeras, después de las barras de color, basada en el código de uno de los proyectos antiguos. Ya tenía soporte para dos fuentes, diferentes paletas y ralentizaciones al final. Para la demostración, se dibujaron nuevas fuentes, que se usan en todas partes, y se agregó un efecto en los bordes de la pantalla.

Al principio quería hacer que los bordes se atenuaran suavemente, pero durante los experimentos preliminares probé opciones con desplazamiento de línea horizontal, me gustó el resultado y decidí no perder más tiempo. Se agrega un ligero sombreado utilizando la característica controvertida del controlador de video NES , silenciamiento de ganancia de componentes de color. La controversia radica en el hecho de que en diferentes versiones regionales y clones de la consola, esta función funciona de manera diferente, pero en esta aplicación no debería haber ningún problema especial (sin contar la llamada RGB PPU , donde los bordes se llenarán de blanco).

Vista


Alrededor del tiempo en que se realizó la escena del subtítulo, surgió espontáneamente la idea de esta escena. La idea inicial era insertarlo en un momento aleatorio, pero al final encajó con éxito en el final. A pesar de su corta duración, la escena consta de tres elementos: simular la escala del sprite, aumentar el número de tonos de gris alternando dos cuadros y reproducir programáticamente una muestra DPCM .

Para simular la escala, se utiliza el hecho de que todos los sprites grandes en NES están compuestos por pequeños, en este caso de tamaño 8x16. Si los cambia uno respecto al otro, puede obtener el efecto de escala o distorsión, que se ve bastante decente con pequeños valores de cambios. Para este efecto, debe multiplicar el desplazamiento de cada sprite desde el centro por una escala, pero dado que el procesador NES no puede hacer frente a una gran cantidad de multiplicaciones enteras pares, se aplica el truco: al comienzo del cuadro, se considera la cuadrícula de coordenadas a lo largo de los ejes X e Y, y la salida del sprite usa estos valores precalculados . Por lo tanto, el número de multiplicaciones requeridas se reduce significativamente: con una pulverización compuesta de elementos 8x8 (64 sprites), solo se requieren 16 (8 + 8) multiplicaciones en lugar de 128 (8 * 8 * 2).

NES solo puede mostrar 4 tonos de gris, incluidos blanco y negro. El efecto imita 7 gradaciones: si visualiza un píxel blanco y blanco a través del marco, será blanco, si gris y gris será gris, y si alterna blanco y gris, visualmente se verá como una gradación intermedia entre blanco y gris. La principal dificultad nuevamente es la preparación de gráficos, es decir, dos medios cuadros de la imagen, que se realizó mediante una serie de manipulaciones manuales en Gale y GIMP . Para reducir el parpadeo, las líneas de los medios cuadros se alternan.



Se requería la reproducción programática de DPCM porque no había espacio para la muestra en mejores formatos, el soporte de hardware no podía reproducir muestras desde la mitad inferior de la memoria, pero no había espacio para una muestra de tal longitud en la memoria superior no conmutable. El fragmento de sonido en sí no es del protector de pantalla original, sino un tintineo que suena bastante similar del conocido juego con acabado cruel, que suena en el momento del acabado real.

Tarjeta de memoria


En desarrollo, la utilidad NES Space Checker se usaba constantemente, lo que visualiza el llenado de los bancos de memoria. Es bastante interesante ver un buen ejemplo de qué y dónde está dentro del programa.



PRG00 ... PRG02 - datos de música
PRG03 : muestra de una escena con una vista
PRG04 ... PRG06 - datos de animación de rotación del cartucho
PRG07 - animación de mosaico en el corredor
PRG08 - animación de rotación de mosaico en el corredor
PRG09 - código de escena de la torre
PRG0A - código de escena con un logotipo giratorio
PRG0B - código de escena con un nombre y un corredor
PRG0C - código de escena con cartucho giratorio, Kirby, View, invaders, Pakman
PRG0D : código de escena con introducciones, ruido, barras de color, subtítulos
PRG0E : el banco principal del código, contiene solo llamadas de todas las escenas
PRG0F - banco de código fijo, reproductor de música, salida de sprites, manejadores de interrupciones

CHR00 - bebé elefante y azulejos para rayas de colores
CHR01 - fuente y ruido
CHR02 - Ver sprite y mosaicos de letras giratorias en el nombre
CHR03 - Azulejos normales de Kirby
CHR04 - Azulejos de Cheshire Kirby
CHR05 : gráficos para una escena con un cartucho giratorio
CHR06 ... CHR0D - animación de logotipo giratorio
CHR0E - una fuente para saludos y animación de mosaicos invasores
CHR0F - Azulejos Pakman
CHR10 ... CHR13 - animación de textura de torre
CHR14 - Azulejos de pasillo
CHR15 - Sprite Mario
CHR16 ... CHR1F - no utilizado

En lugar de una conclusión


Terminaré con un meme combinado: en cualquier situación incomprensible, ¡escriba escenas de demostración, caballeros!

Source: https://habr.com/ru/post/474960/


All Articles