¡Hola a todos!, hay problemas con la web que espero poder arreglar lo antes posible, ¡mil perdones!

Ver índice de webs/blogs

D.E.P.: Andrey Rodionov (1954-2023) [MSXBlog de Konamito] [Leer]


El pasado 29 de mayo, tras dos meses en coma, falleció Andrey Rodionov.

Quizá su nombre no sea conocido en el mundillo ya que firmó solo cuatro juegos a finales de los ochenta como A.R. Crazysoft en la extinta U.R.S.S.:

Estos juegos para mí fueron unos completos desconocidos hasta la llegada de los emuladores. Me tropecé primero con los dos protagonizados por Pistoletov, que desde el principio me llamaron mucho la atención por su calidad sonora y gráfica. No sabía nada más de A.R. Crazysoft; solo que era ruso y que tenía un gran talento como creador de juegos para MSX. Luego les perdí la pista hasta un tiempo después (no recordaba sus nombres) y fue una agradable sorpresa reencontrarme con ellos en una de mis inmersiones en discos duros y repositorios. Pero lo que más me llamó la atención es que habían otros dos juegos creados por Andrey con una calidad similar a los que ya conocía.

En 2021 retomó los juegos, a partir del código fuente que aún conservaba y se puso manos a la obra corrigiendo algunos detalles y aprovechó la ocasión para añadir la traducción al inglés. Más recientemente, sus juegos fueron presentados a la presente edición de Yandrex Retro Games Battle que publicará sus resultados el próximo 10 de junio.

Andrey nació en Moscú el 3 de junio de 1954. Trabajó como compositor musical, programador y administrador de sistemas, entre otras cosas. Aunque destacó como miembro de la Asociación Rusa para la Música Electroacústica (Russian Association for the Electroacoustic Music), dentro de la Unión de Compositores de Rusia.

Hoy cumpliría 69 años. Sirva este texto como tributo a su trabajo. En nuestra mano está recordarle como se merece: disfrutando de sus creaciones como homenaje a título póstumo. D.E.P.

Enlace relacionado: Twitter

Mierdas Miticas: Super Smash T.V. (Game Gear) [Mundo Retrogaming] [Leer]


La versión para Game Gear de Super Smash T.V. fue programada por Probe Entertainment y publicada y distribuida por Flying Edge, saliendo a la venta en 1992, y en 1994 llegó a Estados Unidos y Japón, siendo publicada en este último país por Acclaim Japan. Se trata de una versión bastante floja del original de recreativa, por lo que es un juego de acción cenital bastante mediocre.



Leer más »
SC72MFZEDV43

FujiCup: Celebrando los mejores juegos Atari XL/XE de 8-bits [Atariteca] [Leer]



En el mundo de los videojuegos, la nostalgia siempre encuentra su camino de regreso. Este año, se celebrará la primera FujiCup, una competencia organizada por fanáticos polacos de las computadoras Atari de 8-bits con el propósito de incentivar a los desarrolladores de juegos para esta mítica plataforma.

La competencia otorgará dos premios: el Premio del Jurado y el Premio del Público. Estos reconocimientos serán entregados en efectivo y en especie; y su cuantía dependerá de las contribuciones de los patrocinadores y de la comunidad involucrada en el concurso.

Hasta la fecha, el premio acumulado del jurado asciende a 4679 eslotis polacos -equivalente a unos 1100 USD. El panel de expertos está compuesto por Wojtek «Bocianu» Bocianski, Adam «Borsuk» Stępień, Arkadiusz «Larek» Lubaszka, Paweł «Sikor» Sikorski y Roman «Nekroskop» Gorczyca, entre otros. Cada uno de los miembros del jurado evaluará los juegos en tres categorías: innovación (originalidad/idea); ambientación (música/gráficos/actuación); y jugabilidad (rejugabilidad/diversión). Mediante una escala de 1 a 10 puntos, los jurados asignan una puntuación a cada juego en concurso.

El Premio del Público, por otro lado, se compone de todos los pagos realizados por las personas que participan en la votación. Además, cualquier persona que realice una contribución que supere la cantidad mínima (5 zlotys polacos) adquiere el derecho a votar. Actualmente, el pozo del premio de la audiencia asciende a 1958 PLN.

Los tres primeros lugares recibirán un reconocimiento especial y serán recompensados en base a sus posiciones finales: el primer lugar se llevará el 60% del premio acumulado; el segundo lugar el 30%; y el tercer lugar el 10%.

La votación pública está programada para el 15 de enero hasta el 1 de febrero del 2024. Los participantes han sido cuidadosamente seleccionados por los organizadores del evento y figuran en el sitio web oficial de FujiCup, en la sección "Lista de juegos".

Atari 8-bits revive con el lanzamiento de la versión de «Space Taxi» [Atariteca] [Leer]



Los fanáticos de Atari están de enhorabuena, ya que Andrea Cucchetto (Italia) ha logrado convertir el popular juego «Space Taxi» de Commodore 64 para las computadoras Atari 8-bits, con gráficos encantadores, una jugabilidad desafiante e incluso voces digitalizadas.

Cucchetto, conocido por sus contribuciones a la escena Atari con títulos como «Circo Bianco» (1987), «Hypnotic Land» (1992) y «Conquest of the Crown» (1994), decidió retomar su pasión en 2013. Después de lanzar la versión en disco de "White Circus", se propuso un desafío aún mayor: convertir «Space Taxi» para Atari.

«Space Taxi» fue creado originalmente por John Kutcher en 1984 y se destacó por sus voces digitalizadas y su jugabilidad adictiva. Aunque parecía una tarea desalentadora debido a las limitaciones técnicas de las computadoras Atari 8-bits en comparación con el C64, Andrea se armó de valentía y comenzó el desafiante proyecto.


El primer obstáculo al que se enfrentó fue la resolución. Para garantizar al menos cinco colores por pantalla, optó por una resolución más baja, pero se las arregló para aumentarla mediante técnicas de programación como DLI (Interruptor de línea de datos). A medida que avanzaba en el desarrollo del juego, Cucchetto se encontró con el problema de la falta de memoria disponible para los sprites en movimiento. Sin embargo, optó por utilizar un modo híbrido de caracteres y mapas de bits en niveles con muchos sprites. Este enfoque le permitió simplificar el movimiento de objetos sin comprometer la calidad del juego.

Finalmente, después de superar numerosos desafíos y obstáculos, la versión de «Space Taxi» para Atari 8-bits estaba casi lista. Sin embargo, faltaba un elemento clave: las voces digitalizadas. Afortunadamente, Filippo "Philsan" Santellocco (Suecia) y Janusz "Shanti77" Chabowski (Polonia), conocido por su versión de «Bosconian» para Atari 8-colaboraron con código para crear las muestras de voz en el formato adecuado.


El resultado es un emocionante juego que combina la jugabilidad clásica de «Space Taxi» con los encantadores gráficos y sonidos de las computadoras Atari 8-bits. El juego se ejecuta en máquinas con norma NTSC/PAL y al menos 48KB de memoria; pero se recomiendan 128KB de RAM para disfrutar del audio digitalizado.

Además de su emocionante jugabilidad, esta versión ofrece una variedad de opciones para adaptar la experiencia de juego a tus preferencias. El menú te permite elegir entre diferentes tipos de juego, cada uno con su nivel de dificultad y estilo único. De igual manera, se puede probar los 24 niveles en una sola ronda. Además, si tienes la habilidad y la determinación para superar todas las etapas, serás recompensado con el acceso a la "Pantalla misteriosa".

A medida que la comunidad de Atari continúa creciendo y evolucionando, es emocionante pensar en las posibilidades futuras. ¿Qué otros juegos clásicos podrían resucitar en las computadoras Atari 8-bits? ¿Qué nuevas creaciones y proyectos innovadores están en desarrollo?

Space Taxi for Atari 8-bit computers

(getButton) #text=(Space Taxi) #file=(Tamaño: 66 kB) #icon=(download) #size=(1) #color=(#e72F2a) #info=(Descargar)


Cabe destacar que el propio John Kutcher ha aprobado la distribución gratuita de esta versión para Atari.(alert-success)

Doomed Castle, en desarrollo para A500 [Amigatronics] [Leer]


El espíritu de la época dorada de los juegos retro se reencarna en un nuevo proyecto emocionante: Doomed Castle.

En desarrollo de la mano de MA Software, programado en Blitz Basic por Miguel Ángel Jiménez y con Toni Gálvez encargado de los gráficos, este clon del icónico Castlevania es un proyecto comercial que promete llevarnos de vuelta a las emociones de nuestra infancia con el Amiga 500.

Con una jugabilidad similar a la del Castlevania original, Doomed Castle buscará capturar la esencia y la emoción del clásico juego de acción y plataformas. Los jugadores podrán sumergirse en un mundo oscuro y siniestro, lleno de criaturas aterradoras y desafíos intrigantes. ,Por A medida que avanzan, encontrarán mas secretos e items que ayudarán en el camino» enfrentándose a jefes poderosos en su camino hacia el castillo maldito.

La Posadas Party, un evento imperdible para los amantes del Amiga 500 y los juegos retro, será el escenario perfecto para que Doomed Castle haga su debut. Del 30 de junio al 2 de julio, la localidad de Posadas, Córdoba, se llenará de entusiastas de los videojuegos clásicos que tendrán la oportunidad de probar en exclusiva una demo del juego en desarrollo.

Durante la Posadas Party, los asistentes podrán sumergirse en la atmósfera oscura y misteriosa de Doomed Castle. Podrán experimentar la jugabilidad fluida y adictiva mientras exploran los niveles cuidadosamente diseñados y se enfrentan a enemigos desafiantes. La demo será un adelanto emocionante de lo que está por venir y seguramente generará gran expectación y entusiasmo entre los fanáticos del Amiga y los amantes de los juegos retro.

WinUAE 5.0.0 disponible [Amigatronics] [Leer]


WinUAE 4.1.0 listo para descargar |

El mejor emulador de Amiga se actualiza a su versión 5.0.0 con numerosas correcciones y añadidos. Algunas de ellas:

  • Emulación Amiga 500 no expandida con total precisión de ciclos.
  • -Overflow- del búfer de sprites, sólo en AGA, que podía causar efectos secundarios aleatorios.
  • Corregida la desviación del reloj de sincronización de la CIA.
  • Corregidos numerosos errores en el modo GDI.
  • -Integer scaling- funciona correctamente en los modos Overscan+ y superiores.
  • La opción «interlace artifacts» no era fiable y causaba corrupción de gráficos en modos precisos.
  • Corrección de múltiples errores de emulación de chipset (bitplanes, sprites, blitter).

Mas correciones y los nuevos añadidos mira en https://www.winuae.net/

Retro Entre Amigos – 11×10 – Junio (Verano a las Puertas) [Retro entre amigos] [Leer]


Saludos a tod@s los amigos del retro.

¡¡ Volvemos un nuevo mes! En este caso… ya estamos en Junio y eso nos habla de un Verano que los tenemos a las puertas y que nos promete mil aventuras en nuestras bicis Orbea !!

En esta ocasión, además de correo habitual de los oyentes y preguntas varias, hablaremos de nuestro nuevo sistema de apoyo al podcast a través de la opción “apoyar” de iVoox. Esperamos que os parezca bien y recordad que todo suma !.

En las secciones habituales, tendremos de nuevo la sección “Os traigo un juego”. En ella, nuestro joven compañero Seth Garamonde nos acercará un juego que utiliza el motor del DOOM 2 se trata de “My House” y que, según parece, tiene mucho que descubrir. Estamos deseando meterle mano ¡!!.

Como asunto especial.. tendremos en directo como público a una persona… nuestro amigo José Luis de Almería que ha sido “raptado en secreto” a acudir a REAM nada mas y nada menos que por Karo su mujer que tambien estuvo entre nosotros experimentando en primera persona lo que es grabar uno de nuestros programas, y yo digo…… ESO son regalos GUAYS ¡!!!!!!!!!!!!!!. Desde aquí nuestro cariño por haber acudido a ver en directo la falta de medios, la ausencia de guion y el nulo despliegue de efectivos¡!!

Nuestro amigo Espetero en su sección “El Reparatero”, nos va a explicar como reparar una gloriosa Videopac destruyendo al mismo tiempo la suya y el Dr.Chip nos acercara su sección “cartas en el tiempo” que en este caso serán “enciclopedias en el tiempo” pero con un asunto que sigue siendo de actualidad

Por fin nos da tiempo y traernos la sección “El tonto las gafas” donde comentaremos sobre el pequeño infierno desatado con las actualizaciones de META para sus Quest 2 y daremos un repaso a lo que es PCVR con sus luces y sus sombras.

Todo esto.. y mucho menos… regado de risas pero también de momentos
serios, de cuatro amigos en torno a una mesa bastante cuadrada en la que solo nos faltabas TÚ!!. Vente un día y cuéntalo ¡!!!!!!!!!!!!

Retrosaludos

Enlace a My House —> ENLACE

0x06 Ensamblador ZX Spectrum OXO – ajustes finales [Espamatica] [Leer]


Hemos llegado al capítulo final de Ensamblador para ZX Spectrum OXO. Vamos ha realizar unos ajustes que, si bien no son del todo necesarios, creo que pueden ser de interés.

Añadiremos una opción en el menú para que puedan seleccionar los jugadores el número máximo de tablas que puede haber.

Siguiendo con las tablas, actualmente para finalizar el punto es necesario realizar todos los movimientos posibles (ocupar la totalidad de las celdas), aunque en ocasiones ya sabemos que no es posible ganar y son tablas. Implementaremos la detección de tablas para que detecte si ya no es posible ganar y finalizar el punto.

Propondré unas modificaciones que nos harán ahorrar unos cuantos bytes y ciclos de reloj. Modificaremos los movimientos del Spectrum para que ya no sea tan sencillo ganarle. Por último, vamos a añadir la pantalla de carga.

Menú tablas

Actualmente, el número máximo de tablas lo tenemos declarado en la constante MAXTIES en Var.asm; la borramos.

Localizamos MaxPoints y debajo añadimos la nueva variable para las tablas:

MaxTies: db $05 ; Máximo tablas

Localizamos TitleEspamatica y justo encima añadimos la opción de menú para las tablas:

TitleOptionTies: db $10, INK7, $16, $10, $08, "4. ", $10, INK6 defm "Tablas"

Para que quede más simétrico, localizamos Title3EnRaya y en la parte final de la línea sustituimos $16, $02, $0A por $16, $04, $0A.

En Main.asm vamos a añadir el tratamiento de la nueva opción del menú. Localizamos menu_Time y dos líneas más abajo sutituimos JR NZ, menu_op por:

jr nz, menu_Ties ; No, salta

Localizamos menu_TimeDo y tres líneas más abajo, después de JR menu_op, añadimos el tratamiento de la nueva opción de menú:

menu_Ties: cp KEY4 ; ¿Pulsado 4? jr nz, menu_op ; No, bucle ld a, (MaxTies) ; A = tablas add a, $02 ; A += 2 cp $0a ; ¿A < 10? jr c, menu_TiesDo ; Sí, salta ld a, $03 ; A = 3 menu_TiesDo: ld (MaxTies), a ; Actualiza tablas jr menu_op ; Bucle

Si se ha pulsado la tecla cuatro, se añade dos al número máximo de tablas, si es mayor de nueve se pone a tres, y se carga en memoria.

Tanto este rango de valores, como la diferencia entre uno y otro valor lo podéis modificar a vuestro gusto. También lo podéis cambiar a vuestro gusto en puntos y tiempo.

Una vez que tenemos el número máximo de tablas guardado en memoria, hay que usarlo. Localizamos la etiqueta loop_reset, la línea LD B, MAXTIES y la sutituímos por las siguientes:

ld a, (MaxTies) ; A = máximo tablas ld b, a ; B = A

Ya solo nos queda pintar el valor seleccionado. En Screen.asm, localizamos PrintOptions y, justo por encima de JP PrintBCD, añadimos las líneas siguientes:

call PrintBCD ; Lo pinta ld b, INI_TOP-$10 ; B = coord Y call AT ; Posiciona cursor ld hl, MaxTies ; HL = valor tiempo

Compilamos, cargamos en el emulador y comprobamos que ya podemos definir el número de tablas, y que al alcanzarse se finaliza la partida.

Ensamblador ZX Spectrum - menú tablasEnsamblador ZX Spectrum – menú tablas
Detección de tablas

Actualmente, para que se detecten tablas tienen que estar todas las celdas ocupadas y que no haya tres en raya. En realidad, es posible saber si el punto terminará en tablas antes de que el tablero este lleno.

Vamos a Game.asm e implementamos la detección de tablas.

Para saber si hay posibilidad de algún movimiento, sólo hay que saber si queda alguna combinación en la que las celdas estén ocupadas por un solo jugador, o por ninguno.

; ------------------------------------------------------------------- ; Comprueba si hay tablas. ; Para poder comprobar si hay tablas. ; ; Salida: Z -> No hay tablas. ; NZ -> Hay tablas. ; ; Altera el valor de los registros AF, BC, DE, HL e IX. ; ------------------------------------------------------------------- CheckTies: ld b, $f0 ; B = máscara celdas un jugador ld c, $0f ; B = máscara celdas otro jugador

Cargamos en B la máscara para quedarnos con las celdas que ocupa un jugador, y en C la máscara para el jugador dos.

checkTies_check123: ld hl, Grid ; HL = dirección grid ld a, (hl) ; A = valor celda 1 inc hl ; HL = dirección celda 2 add a, (hl) ; A+= valor celda 2 inc hl ; HL = dirección celda 3 add a, (hl) ; A+= valor celda 2 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale

Apuntando HL a Grid, sumamos en A el valor de las tres celdas, incrementanto HL para pasar de una celda a otra. Comprobamos si hay alguna celda ocupada por un jugador, y de no ser así salimos. Si sí las hay, comprobamos si hay celdas ocupadas por el otro jugador, y si no las hay salimos.

Las dos comprobaciones siguientes tiene la misma estructura.

checkTies_check456: inc hl ; A = dirección celda 4 ld a, (hl) ; A = valor celda 4 inc hl ; HL = dirección celda 5 add a, (hl) ; A+= valor celda 5 inc hl ; HL = dirección celda 6 add a, (hl) ; A+= valor celda 6 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale checkTies_check789: inc hl ; A = dirección celda 7 ld a, (hl) ; A = valor celda 7 inc hl ; HL = dirección celda 8 add a, (hl) ; A+= valor celda 8 inc hl ; HL = dirección celda 9 add a, (hl) ; A+= valor celda 9 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale

Fijaos bien en como vamos recorriendo las celdas con HL, esto nos va ayuda a ahorrar unos bytes en una implementación que hicimos anteriormente.

Las siguientes comprobaciones no las podemos hacer cambiando de celda con HL, ya que no son numéricamente contiguas; usamos IX.

checkTies_check147: ld ix, Grid-$01 ; IX = dirección Grid - 1 ld a, (ix+$01) ; A = valor celda 1 add a, (ix+$04) ; A+= valor celda 4 add a, (ix+$07) ; A+= valor celda 7 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale

El resto de comprobaciones tienen la misma estructura. checkTies_check258:

checkTies_check258: ld a, (ix+$02) ; A = valor celda 2 add a, (ix+$05) ; A+= valor celda 5 add a, (ix+$08) ; A+= valor celda 8 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale checkTies_check369: ld a, (ix+$03) ; A = valor celda 3 add a, (ix+$06) ; A+= valor celda 6 add a, (ix+$09) ; A+= valor celda 9 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale checkTies_check159: ld a, (ix+$01) ; A = valor celda 1 add a, (ix+$05) ; A+= valor celda 5 add a, (ix+$09) ; A+= valor celda 9 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret z ; Ninguna, sale checkTies_check357: ld a, (ix+$03) ; A = valor celda 3 add a, (ix+$05) ; A+= valor celda 5 add a, (ix+$07) ; A+= valor celda 7 ld d, a ; Preserva A en D and b ; A = celdas ocupadas por un jugador ret z ; Ninguna, sale ld a, d ; Recupera A desde D and c ; A = celdas ocupadas por otro jugador ret ; Sale con Z en estado correcto

Con esto ya tenemos la predicción de si va a haber tablas, sólo queda ir a Main.asm y usarla.

Localizamos loop_tie y tres líneas más abajo sustituimos:

ld a, $09 ; A = 9 cp (hl) ; ¿Contador = 9? jr nz, loop_cont ; No, salta

Por:

call CheckTies ; ¿Algún movimiento posible? jr z, loop_cont ; No, salta

Ya no hace falta esperar a que el tablero esté lleno para saber si hay o no tablas. Llamamos a CheckTies y si no hay tablas seguimos con el punto.

Compilamos, cargamos en el emulador y vemos los resultados.

Ensamblador ZX Spectrum - predicción de tablasEnsamblador ZX Spectrum – predicción de tablas

Quizá veáis un comportamiento que os hace pensar que algo no funciona. Veis la línea uno, dos, tres libre, pero sabes que el Spectrum va a ocupar una celda, luego tú otra y por eso debería marcar tablas.

El sistema precide pero no adivinia. Imaginaos que en una fila hay dos celdas libres y le toca mover al jugador que no tiene la celda ocupada. Bueno, va a ocupar una de las celdas así que ya sabemos que son tablas, pero imaginad que el jugador se duerme en los laureles y pierde el turno, el otro jugador ocupa otra celda y solo queda una libre, y sigue sin poderse predecir tablas, si el otro jugador se vuelve a dormir, pierde turno otra vez y el primer jugador consigue tres en raya.

Ahorramos bytes y ciclos de reloj

Vamos a implementar varias modificaciones para ahorrar bytes y ciclos de reloj.

Las primeras de ellas van a ser en Game.asm, sobre el conjunto de rutinas CheckWinner y ZxMove, aplicando la forma en la que hemos implementado CheckTies en las líneas horizontales, las numéricamente contiguas.

Vamos a la etiqueta, ChechWinner_check, localizamos las líneas siguientes:

ld a, (ix+1) ; A = celda 1 add a, (ix+2) ; A+= celda 2 add a, (ix+3) ; A+= celda 3

Y las sustituimos por:

ld hl, Grid ; HL = dirección celda 1 ld a, (hl) ; A = valor celda 1 inc hl ; HL = dirección celda 2 add a, (hl) ; A+= valor celda 2 inc hl ; HL = dirección celda 3 add a, (hl) ; A+= valor celda 3

Localizamos las líneas:

ld a, (ix+4) ; A = celda 4 add a, (ix+5) ; A+= celda 5 add a, (ix+6) ; A+= celda 6

Y las sustituimos por:

inc hl ; HL = dirección celda 4 ld a, (hl) ; A = valor celda 4 inc hl ; HL = dirección celda 5 add a, (hl) ; A+= valor celda 5 inc hl ; HL = dirección celda 6 add a, (hl) ; A+= valor celda 6

Localizamos las líneas:

ld a, (ix+7) ; A = celda 7 add a, (ix+8) ; A+= celda 8 add a, (ix+9) ; A+= celda 9

Y las sustituimos por:

inc hl ; HL = dirección celda 7 ld a, (hl) ; A = valor celda 7 inc hl ; HL = dirección celda 8 add a, (hl) ; A+= valor celda 8 inc hl ; HL = dirección celda 9 add a, (hl) ; A+= valor celda 9

Esta parte está lista, añadid en los comentarios de la rutina a HL como registro afectado.

Esta es la comparativa entre ambas versiones:

VersiónCiclosBytes
1688 / 641118
2638 / 591111

Como se observa, estamos ahorrando cincuenta ciclos de reloj y siete bytes. Compilamos, cargamos en el emulador y vemos como todo sigue funcionando.

Procedemos a modificar ZxMove, en concreto dos partes de este conjunto de rutinas. Localizamos zxMoveToWin_123 y sustituimos:

ld a, (ix+$01) ; A = valor celda 1 add a, (ix+$02) ; A+= valor celda 2 add a, (ix+$03) ; A+= valor celda 3

Por:

ld hl, Grid ; HL = dirección celda 1 ld a, (hl) ; A = valor celda 1 inc hl ; HL = dirección celda 2 add a, (hl) ; A+= valor celda 2 inc hl ; HL = dirección celda 3 add a, (hl) ; A+= valor celda 3

Localizamos zxMoveToWin_456 y sustituimos:

ld a, (ix+$04) ; A = valor celda 4 add a, (ix+$05) ; A+= valor celda 5 add a, (ix+$06) ; A+= valor celda 6

Por:

ld hl, Grid+$03 ; HL = dirección celda 4 ld a, (hl) ; A = valor celda 4 inc hl ; HL = dirección celda 5 add a, (hl) ; A+= valor celda 5 inc hl ; HL = dirección celda 6 add a, (hl) ; A+= valor celda 6

Localizamos zxMoveToWin_789 y sustituimos:

ld a, (ix+$07) ; A = valor celda 7 add a, (ix+$08) ; A+= valor celda 8 add a, (ix+$09) ; A+= valor celda 9

Por:

ld hl, Grid+$06 ; HL = dirección celda 7 ld a, (hl) ; A = valor celda 7 inc hl ; HL = dirección celda 8 add a, (hl) ; A+= valor celda 8 inc hl ; HL = dirección celda 9 add a, (hl) ; A+= valor celda 9

Ya hemos terminado con la primera parte. La diferencia principal con CheckTies y CheckWinner es que, aunque son celdas numéricamente contiguas, el paso de la celda tres a la cuatro y de la seis a la siete no es con INC HL, ya que ToMove altera el valor de HL.

Localizamos zxMoveAttack_123 y sustituimos:

ld a, (ix+$01) ; A = valor celda 1 add a, (ix+$02) ; A+= valor celda 2 add a, (ix+$03) ; A+= valor celda 3

Por:

ld hl, Grid ; HL = dirección celda 1 ld a, (hl) ; A = valor celda 1 inc hl ; HL = dirección celda 2 add a, (hl) ; A+= valor celda 2 inc hl ; HL = dirección celda 3 add a, (hl) ; A+= valor celda 3

Localizamos zxMoveAttack_456 y sustituimos:

ld a, (ix+$04) ; A = valor celda 4 add a, (ix+$05) ; A+= valor celda 5 add a, (ix+$06) ; A+= valor celda 6

Por:

ld hl, Grid+$03 ; HL = dirección celda 4 ld a, (hl) ; A = valor celda 4 inc hl ; HL = dirección celda 5 add a, (hl) ; A+= valor celda 5 inc hl ; HL = dirección celda 6 add a, (hl) ; A+= valor celda 6

Localizamos zxMoveAttack_789 y sustituimos:

ld a, (ix+$07) ; A = valor celda 7 add a, (ix+$08) ; A+= valor celda 8 add a, (ix+$09) ; A+= valor celda 9

Por:

ld hl, Grid+$06 ; HL = dirección celda 7 ld a, (hl) ; A = valor celda 7 inc hl ; HL = dirección celda 8 add a, (hl) ; A+= valor celda 8 inc hl ; HL = dirección celda 9 add a, (hl) ; A+= valor celda 9

Hacemos otra modificación, en zxMoveDefence_cornerBlock34 y en zxMoveDefence_cornerBlock67, que nos hace ahorrar ciclos de reloj, pero ningún byte.

Sustituimos en zxMoveDefence_cornerBlock34:

ld a, (ix+$03) ; A = valor celda 3 add a, (ix+$04) ; A+= valor celda 4

Por:

ld hl, Grid+$02 ; A = dirección celda 3 ld a, (hl) ; A = valor celda 3 inc hl ; HL = dirección celda 4 add a, (hl) ; A+= valor celda 4

En zxMoveDefence_cornerBlock67 sustituimos:

ld a, (ix+$06) ; A = valor celda 6 add a, (ix+$07) ; A+= valor celda 7

Por:

ld hl, Grid+$05 ; A = dirección celda 6 ld a, (hl) ; A = valor celda 6 inc hl ; HL = dirección celda 7 add a, (hl) ; A+= valor celda 7

Las modificaciones en Game.asm ya están. Como ya comenté, añadid en los comentarios de la rutina a HL como registro afectado. Ya se nos olvidó antes, pues el registro HL ya se veía afectado por la rutina zxMoveGeneric.

Esta es la comparativa entre las dos versiones de ZxMove:

VersiónCiclosBytes
14632 / 4079808
24532 / 3979802

La versión dos ocupa seis bytes menos y tarda cien ciclos menos que la uno, lo que parece poco si lo comparamos con el ahorro en bytes de CheckWinner, con menos modificaciones. Recordad que allí el paso de la celda tres a la celda cuatro y de la seis a la siete lo hacemos con  INC HL y aquí no podemos.

La diferencia de INC HL con LD HL, Grid es de cuatro ciclos y dos bytes, y eso nos limita el ahorro.

Si tuviéramos problemas de capacidad, que no es así, podemos ahorrar otro buen puñado de bytes pintando la misma ficha, con distinto color, para ambos jugadores.

Vamos a Sprite.asm y comentamos la definición Sprite_P2. Por otro lado, las definiciones de Sprite_CROSS, Sprite_SLASH y Sprite_MINUS las ponemos al inicio del archivo, quedando así:

; ------------------------------------------------------------------- ; Fichero: Sprite.asm ; ; Definición de los gráficos. ; ------------------------------------------------------------------- ; Sprite de la cruceta Sprite_CROSS: db $18, $18, $18, $ff, $ff, $18, $18, $18 ; $90 ; Sprite de la línea vertical Sprite_SLASH: db $18, $18, $18, $18, $18, $18, $18, $18 ; $91 ; Sprite de la línea hortizontal Sprite_MINUS: db $00, $00, $00, $ff, $ff, $00, $00, $00 ; $92 ; Sprite del jugador 1 Sprite_P1: db $c0, $e0, $70, $38, $1c, $0e, $07, $03 ; $93 db $03, $07, $0e, $1c, $38, $70, $e0, $c0 ; $94 ; ; Sprite del jugador 2 ; Sprite_P2: ; db $03, $0f, $1c, $30, $60, $60, $c0, $c0 ; $95 Arriba/Izquierda ; db $c0, $f0, $38, $0c, $06, $06, $03, $03 ; $96 Arriba/Derecha ; db $c0, $c0, $60, $60, $30, $1c, $0f, $03 ; $97 Abajo/Izquierda ; db $03, $03, $06, $06, $0c, $38, $f0, $c0 ; $98 Abajo/Derecha

Comentar el sprite del jugador dos no sólo obliga a modificar la rutina que pinta las fichas, también obliga a modificar la rutina que pinta el tablero, ya que cambian los UDG. Hemos subido a la parte de arriba los sprites del tablero para sólo modificar una vez la rutina que lo pinta, y para que si más adelante decidimos volver a pintar las dos fichas, no se vea afectada.

Al comentar Sprite_P2 ahorramos treinta y dos bytes. No parece mucho, pero en ciertas situaciones nos puede salvar.

Vamos a Var.asm y modificamos la definición de Board_1 y _2 y la dejamos así:

; Líneas verticales del tablero. Board_1: db $12, $00, $13, $00 db $20, $20, $20, $20, $91, $20, $20, $20, $20, $91, $20, $20, $20 db $20, $ff ; Líneas horizontales del tablero. Board_2: db $92, $92, $92, $92, $90, $92, $92, $92, $92, $90, $92, $92, $92 db $92, $ff

Compilamos, cargamos en el emulador y vemos los resultados, concretamente el desastre que hemos organizado.

Ensamblador ZX Spectrum - el caosEnsamblador ZX Spectrum – el caos

Que la ficha del  jugador dos se pinte mal lo esperábamos, pero ¿qué pasa con el tablero? Hemos cambiado la posición de la definición de los sprites, pero UDG sigue apuntando a Sprite_P1.

Vamos a Main.asm, y debajo de la etiqueta Main sustituimos:

ld hl, Sprite_P1 ; HL = dirección Sprite_P1

Por:

ld hl, Sprite_CROSS ; HL = dirección Sprite_CROSS

Cambiad también el comentario de la línea de abajo.

Compilamos, cargamos en el emulador y vemos que el tablero se pinta bien, pero las fichas no. Tranquilos, era lo esperado.

Ensamblador ZX Spectrum - tres en raya malditasEnsamblador ZX Spectrum – tres en raya malditas

Vamos a modificar la rutina que pinta las fichas para que lo haga bien, o no, lo podéis dejar así; tres en raya malditas.

Localizamos printOXO_X y las líneas en las que se carga el UDG en A. Le sumamos tres al valor que carga:

ld      a, $90        pasa a        ld      a, $93
ld      a, $91        pasa a        ld      a, $94

Localizamos printOXO_Y y las líneas en las que se carga el UDG en A. Le sumamos tres al valor que carga:

ld      a, $92        pasa a        ld      a, $95
ld      a, $93        pasa a        ld      a, $96
ld      a, $94        pasa a        ld      a, $97
ld      a, $95        pasa a        ld      a, $98

Con esto, si decidimos pintar dos fichas distintas, se pintaría el círculo.

Como ahora estamos en la situación de pintar una sola ficha, comentamos las líneas:

ld a, $95 ; A = 1er sprite ld a, $98 ; A = 4º sprite

Y debajo de las mismas añadimos la línea:

ld a, $93 ; A = 1er sprite

Comentamos las líneas:

ld a, $96 ; A = 2º sprite ld a, $97 ; A = 3er sprite

Y debajo de las mismas añadimos la línea:

ld a, $94 ; A = 2º sprite

Un poco de lío, ¿verdad? El aspecto final es este:

printOXO_X: ld a, INKPLAYER1 ; A = tinta jugador 1 call INK ; Cambia tinta ld a, $93 ; A = 1er sprite rst $10 ; Lo pinta ld a, $94 ; A = 2º sprite rst $10 ; Lo pinta dec b ; B = línea inferior call AT ; Posiciona cursor ld a, $94 ; A = 2º sprite rst $10 ; Lo pinta ld a, $93 ; A = 2º sprite rst $10 ; Lo pinta ret ; Sale printOXO_Y: ld a, INKPLAYER2 ; A = tinta jugador 2 call INK ; Cambia tinta ;ld a, $95 ; A = 1er sprite ld a, $93 ; A = 1er sprite rst $10 ; Lo pinta ;ld a, $96 ; A = 2º sprite ld a, $94 ; A = 2º sprite rst $10 ; Lo pinta dec b ; B = línea inferior call AT ; Posiciona cursor ;ld a, $97 ; A = 3er sprite ld a, $94 ; A = 2º sprite rst $10 ; Lo pinta ;ld a, $98 ; A = 4º sprite ld a, $93 ; A = 1er sprite rst $10 ; Lo pinta ret ; Sale

De esta manera, si queremos volver a dibujar las dos fichas, en Sprite.asm descomentamos Sprite_P2, y en printOXO_Y alternamos los comentarios en las líneas LD A, ….

Con esto ya se pintan bien las fichas en el tablero, pero no en la parte de información de la partida.

Volvemos a Var.asm y modificamos player1_figure que ahora es así:

player1_figure: db $16, $04, $00, $90, $91, $0d, $91, $90

Y la dejamos así:

player1_figure: db $16, $04, $00, $93, $94, $0d, $94, $93

Modificamos player2_figure que ahora es así:

player2_figure: db $16, $04, $1b, $92, $93 db $16, $05, $1b, $94, $95, $ff

Y la dejamos así:

player2_figure: db $16, $04, $1b, $93, $94 db $16, $05, $1b, $94, $93, $ff

Por último, añadimos, comentada, la definición para pintar fichas distintas.

; player2_figure: db $16, $04, $1b, $95, $96 ; db $16, $05, $1b, $97, $98, $ff

Compilamos, cargamos en el emulador y vemos los resultados.

Ensamblador ZX Spectrum - una fichaEnsamblador ZX Spectrum – una ficha

Es decisión vuestra pintar la misma ficha en distinto color para los dos jugadores, o pintar distintas para cada jugador. Si utilizáramos una televisión en blanco y negro no habría ninguna duda.

Si mantenéis todas las modificaciones, hemos ahorrado cuarenta y cinco bytes y ciento cincuenta ciclos de reloj. Si decidís pintar distintas fichas para cada jugador, el ahorro de bytes se queda en trece.

Movimiento del Spectrum

Si ya habéis jugado varias partidas contra el Spectrum, habréis averiguado la forma de ganarle, siempre, al iniciar vosotros la partida, y es que hay al menos un movimiento que el Spectrum no sabe defender, no se lo hemos programado.

El movimiento en concreto es ocupar dos celdas de la esquina: la dos y la seis o la seis y la ocho. Si ocupamos la celda dos, el Spectrum ocupa la cinco, movemos a la celda seis y el Spectrum mueve a la siete, movemos a la tres y ya tenemos dos jugadas de tres en raya: celdas uno, dos y tres y celdas tres, seis y nueve.

En Game.asm, localizamos zxMoveAttack_123 y por encima de ella implementamos las líneas que hacen que ya no se pueda ganar al Spectrum realizando ese movimiento.

; ------------------------------------------------------------------- ; Movimiento defensivo de esquina. ; ------------------------------------------------------------------- zxMoveDefence_corner24: ld a, (ix+$02) ; A = valor celda 2 add a, (ix+$04) ; A+= valor celda 4 cp b ; ¿A = B? jr nz, zxMoveDefence_corner26 ; No, salta ld c, KEY1 ; C = tecla 1 call ToMove ; Mueve a celda 1 ret z ; Si es correcto, sale

Comprobamos si el jugador uno tiene ocupadas las casillas dos y cuatro, en cuyo caso movemos a la casilla uno si es posible.

El resto de comprobaciones tienen la misma estructura.

zxMoveDefence_corner26: ld a, (ix+$02) ; A = valor celda 2 add a, (ix+$06) ; A+= valor celda 6 cp b ; ¿A = B? jr nz, zxMoveDefence_corner84 ; No, salta ld c, KEY3 ; C = tecla 3 call ToMove ; Mueve a celda 3 ret z ; Si es correcto, sale zxMoveDefence_corner84: ld a, (ix+$08) ; A = valor celda 8 add a, (ix+$04) ; A+= valor celda 4 cp b ; ¿A = B? jr nz, zxMoveDefence_corner86 ; No, salta ld c, KEY7 ; C = tecla 7 call ToMove ; Mueve a celda 3 ret z ; Si es correcto, sale zxMoveDefence_corner86: ld a, (ix+$08) ; A = valor celda 8 add a, (ix+$06) ; A+= valor celda 6 cp b ; ¿A = B? jr nz, zxMoveAttack_123 ; No, salta ld c, KEY9 ; C = tecla 9 call ToMove ; Mueve a celda nueve ret z ; Si es correcto, sale

Aunque la jugada se da en dos esquinas, cubrimos las cuatro.

Justo encima de zxMoveDefence_cornerBlock2938Cont está la línea JR NZ, zxMoveAttack_123, la modificamos y la dejamos así:

jr nz, zxMoveDefence_corner24 ; No, no mov cruz, salta

Si compiláis y jugáis algunas partidas contra el Spectrum veréis que ahora no es posible ganarle con esa jugada, no obstante sigue siendo posible ganarle, sigue habiendo jugadas que no sabe defender.

Ensamblador ZX Spectrum - más difcil ganarEnsamblador ZX Spectrum – más difícil ganar
Dificultad

Ahora es más difícil ganar al Spectrum, debemos esperar a que sea él el que empiece la partida y, dependiendo del movimiento que haga, podremos ganarle.

Vamos a añadir otra opción en el menú para poder seleccionar el nivel de dificultad: uno para que no cubra la jugada en la esquina, y dos para que si lo haga.

En Var.asm, después de MaxTies, añadimos la variable para el nivel de dificultad:

Level: db $02 ; Nivel de dificultad

Al añadir una nueva opción de menú, está última queda pegada a la línea Espamática. Subimos todas las opciones del menú una línea, quedando así:

TitleOptionStart: db $10, INK1, $13, $01, $16, $07, $08, "0. " db $10, INK5 defm "Empezar" TitleOptionPlayer: db $10, INK7, $13, $01, $16, $09, $08, "1. " db $10, INK6 defm "Jugadores" TitleOptionPoint: db $10, INK7, $16, $0b, $08, "2. ", $10, INK6 defm "Puntos" TitleOptionTime: db $10, INK7, $16, $0d, $08, "3. ", $10, INK6 defm "Tiempo" TitleOptionTies: db $10, INK7, $16, $0f, $08, "4. ", $10, INK6 defm "Tablas"

Tras la definición de TitleOptionTies añadimos la de la dificultad:

TitleOptionLevel: db $10, INK7, $16, $11, $08, "5. ", $10, INK6 defm "Dificultad"

En Screen.Asm localizamos PrintOptions y restamos una a todas las asignaciones de la coordenada Y:

LD B, INI_TOP-$0A          pasa a       LD B,INI_TOP-$09
LD B, INI_TOP-$0C          pasa a       LD B,INI_TOP-$0B
LD B, INI_TOP-$0E          pasa a       LD B,INI_TOP-$0D
LD B, INI_TOP-$10          pasa a       LD B,INI_TOP-$0F

Por encima de JP PrintBCD añadimos las líneas siguientes:

call PrintBCD ; Lo pinta ld b, INI_TOP-$11 ; B = coord Y call AT ; Posiciona cursor ld hl, Level ; HL = valor dificultad

Siendo el aspecto final de la rutina el siguiente:

; ------------------------------------------------------------------- ; Pinta los valores de las opciones. ; ; Altera el valor de los registros AF, BC y HL. ; ------------------------------------------------------------------- PrintOptions: ld a, INK4 ; A = tinta verde call INK ; Cambia tinta ld b, INI_TOP-$09 ; B = coord Y ld c, INI_LEFT-$15 ; C = coord X call AT ; Posiciona cursor ld hl, MaxPlayers ; HL = valor jugadores call PrintBCD ; Lo pinta ld b, INI_TOP-$0b ; B = coord Y call AT ; Posiciona cursor ld hl, MaxPoints ; HL = valor puntos call PrintBCD ; Lo pinta ld b, INI_TOP-$0d ; B = coord Y call AT ; Posiciona cursor ld hl, seconds ; HL = valor tiempo call PrintBCD ; Lo pinta ld b, INI_TOP-$0f ; B = coord Y call AT ; Posiciona cursor ld hl, MaxTies ; HL = valor tiempo call PrintBCD ; Lo pinta ld b, INI_TOP-$11 ; B = coord Y call AT ; Posiciona cursor ld hl, Level ; HL = valor dificultad jp PrintBCD ; Lo pinta y sale

En Main.asm, localizamos menu_Ties y debajo la línea CP KEY4. Tras esta línea sustituimos JR NZ, menu_op por:

jr nz, menu_Level ; No, bucle

Después de menu_TiesDo, tras la línea JR menu_op, añadimos las líneas de tratamiento de la nueva opción de menú:

menu_Level: cp KEY5 ; ¿Pulsado 5? jr nz, menu_op ; No, bucle ld a, (Level) ; A = dificultad xor $03 ; Alterna entre 1 y 2 ld (Level), a ; Actualiza en memoria jr menu_op ; Bucle

Por último, en Game.asm localizamos zxMoveDefence_corner24, y justo debajo de ella añadimos:

ld a, (Level) ; A = dificultad cp $01 ; ¿Dificultad = 1? jr z, zxMoveAttack_123 ; Sí, salta

Con estas líneas, si el nivel de dificultad es uno no se comprueba la jugada de esquina, compilad y probad.

Pantalla de carga

Por último, vamos a añadir la pantalla de carga. ¿Y que aporta si ya hemos visto como se hace en ZX-Pong y Batalla espacial? Pues esta vez lo vamos a hacer distinto, ya que no vamos a cargar la pantalla en la VideoRAM, la cargaremos en otra dirección de memoria y luego haremos que aparezca de golpe.

Esta es la pantalla de carga, que podéis descargar desde aquí.

Ensamblador ZX Spectrum - Tres en rayaEnsamblador ZX Spectrum – Tres en raya

Por favor, sed benévolos, el arte nunca ha sido lo mío. Veré con buenos ojos que diseñéis vuestra propia pantalla de carga, que seguro que es mejor que ésta; difícil no debe ser.

Para poder cargar la pantalla de carga en un área de memoria y después volcarla de golpe en la VideoRAM, necesitamos implementar la rutina que lo haga en un archivo aparte, y compilarlo por separado.

El proceso de carga hará lo siguiente:

  • Carga el cargador.
  • Carga la rutina que vuelca la pantalla de carga en la dirección de memoria 24200.
  • Carga la pantalla de carga en la dirección 24250.
  • Ejecuta la rutina que vuelca la pantalla de carga a la VideoRAM.
  • Carga el programa de tres en raya en la dirección 24200.
  • Carga la rutina de interrupciones en la dirección 32348.
  • Ejecuta el programa de tres en raya.

Lo primero que vamos a ver es el cargador que desarrollamos en Basic para hacer todo lo expuesto arriba.

10 CLEAR 24200 20 INK 0: PAPER 4: BORDER 4: CLS 30 POKE 23610,255: POKE 23739,111 40 LOAD ""CODE 24200 50 LOAD ""CODE 24250 60 RANDOMIZE USR 24200 70 LOAD ""CODE 24200 80 LOAD ""CODE 32348 90 CLS 100 RANDOMIZE USR 24200

No olvidéis guardarlo con SAVE”TresEnRaya” LINE 10.

El siguiente paso es implemetar la rutina que vuelca la pantalla de carga a la VideoRAM. Creamos el archivo LoadScr.asm y agregamos las siguientes líneas:

; ------------------------------------------------------------------- ; LoadScr.asm ; ; La pantalla de carga se cargará en $5eba, y esta rutina la pasará ; a la VideoRAM para que aparezca de golpe y luego limpiará la zona ; dónde se había cargado inicialmente. ; La limpieza de ese área de memoria no es necesaria, pero lo hacemos ; por si tenemos que depurar, no encontrar código que en realidad sean ; restos de la pantalla de carga. ; ------------------------------------------------------------------- org $5e88 ; Dirección de carga ld hl, $5eba ; HL = dirección dónde está la pantalla ld de, $4000 ; DE = dirección VideoRAM ld bc, $1b00 ; Longitud de la pantalla ldir ; Vuelca la pantalla ld hl, $5eba ; HL = dirección dónde está la pantalla ld de, $5ebb ; Dirección siguiente ld bc, $1aff ; Longitud de la pantalla - 1 ld (hl), $00 ; Limpia la primera posición ldir ; Limpia el resto ret

La pantalla de carga la cargamos en $5eba. Esta rutina copia a la VideoRAM desde esa dirección $1B00 posiciones (6912 bytes), todo el área de píxeles y atributos.

Una vez copiado, limpia el área de memoria en la que se cargó la pantalla; no es necesario, pero si tenemos que depurar evitamos que quede código residual que nos pueda confundir.

Ya solo nos queda modificar el script que tenemos para compilar y generar el .tap final. La versión para Windows queda así:

echo off cls echo Compilando oxo pasmo --name TresEnRaya --tap Main.asm oxo.tap oxo.log echo Compilando int pasmo --name Int --tap Int.asm int.tap int.log echo Compilando loadscr pasmo --name LoadScr --tap LoadScr.asm loadscr.tap loadscr.log echo Generando TresEnRaya copy /b /y cargador.tap+loadscr.tap+TresEnRayaScr.Tap+oxo.tap+int.tap TresEnRaya.tap echo Proceso finalizado

El aspecto de la versión para Linux sería éste:

clear echo Compilando oxo pasmo --name TresEnRaya --tap Main.asm oxo.tap oxo.log echo Compilando int pasmo --name Int --tap Int.asm int.tap int.log echo Compilando loadscr pasmo --name LoadScr --tap LoadScr.asm loadscr.tap loadscr.log echo Generando TresEnRaya cat cargador.tap loadscr.tap TresEnRayaScr.Tap oxo.tap int.tap > TresEnRaya.tap echo Proceso finalizado

Y con esto hemos terminado. Compilad, cargad en el emulador y a jugar.

Ensamblador ZX Spectrum, conclusión

En este capítulo hemos añadido dos opciones al menú de inicio, somos capaces de predecir si va a haber tablas antes de que el tablero esté lleno, hemos ahorrado bytes y ciclos de reloj, modificado los movimientos del Spectrum para que sea más difícil ganarle y añadido un pantalla de carga que no se muestra poco a poco, se muestra de golpe.

En este tutorial hemos ido mucho más rápido que en los anteriores, ya tenemos los conocimientos suficientes como para que no sea necesario explicar las instrucciones una a una.

Todo el código que hemos generado lo podéis descargar desde aquí.

Ensamblador para ZX Spectrum OXO por Juan Antonio Rubio García.
Esta obra está bajo licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional License.

Y recuerda, si lo usas no te limites a copiarlo, intenta entenderlo y adaptarlo a tus necesidades.

Documentadas nuevas versiones de juegos para Magnet System gracias a Hugo Tomás Benedet [Recreativas.org] [Leer]


Recreativas.org

Hugo Tomás Benedet ha localizado nuevos diskettes para el sistema Magnet de EFO, entre los que se encuentran versiones que no estaban documentadas, además de localizar lo que parecen distintas revisiones de algunos de estos títulos, tal como se indican en las pegatinas de los diskettes.

Leer más en: https://www.recreativas.org/noticias/2023/06/02/documentadas-nuevas-versiones-de-juegos-para-magnet-system-gracias-a-hugo-tomas-benedet-582
Recreativas.org - Base de datos de máquinas recreativas españolas.
Web: www.recreativas.org

Disney’s Hercules (1997) [Insert Coin] [Leer]


Cuando hablamos de videojuegos basados en las peliculas de animación de Disney, enseguida nos vienen a la cabeza infinidad de títulos de plataformas de la era de los 16 bits como Aladdin, The Jungle Book o The Lion King. Videojuegos muy cuidados a nivel técnico y artístico, fieles al producto original y con una gran jugabilidad que terminó prácticamente convirtiendo a estos títulos en un subgénero en sí mismos, y que representan muchos de los mejores videojuegos de plataformas de la década de los 90.

No obstante, a finales de dicha época el salto de los 16 a los 32 bits y, consecuentemente, del 2D a entornos tridimensionales iba a afectar directamente a este tipo de lanzamientos y a la estrategia de Disney en lo que a lanzamientos de videojuegos se refiere. Paralelamente, las películas de animación clásica de Disney empezaban a perder adeptos frente a las nuevas producciones tridimensionales lideradas por Pixar (que terminó siendo propiedad de la propia Disney), por lo que el atractivo de los personajes de las películas cada vez era menor para basar un videojuego en los mismos.

Es por todo esto que mucha gente considera a Disney’s Hercules como el último gran juego de plataformas bidimensional con el sello de Disney. Un título que aunque fue lanzado en plena era de los 32 bits conservaba el espíritu dejado por los juegos anteriores.

Con cambios nimios, el juego sigue la sinopsis de la película de 1997. El hijo de Zeus, Hércules, ha sido despojado de su divinidad y es enviado a la Tierra para demostrar que es un verdadero héroe y, por tanto, volver a recuperarla. La aventura se desarrollará a través de una serie de pruebas hasta el enfrentamiento final con Hades.

El juego se nos presenta con tres niveles de dificultad, fácil (con dos niveles menos), media y hercúlea, siendo principalmente un plataformas bidimensional de desplazamiento lateral. No obstante, el juego hace uso de la potencia superior de las máquinas en las que fue lanzado (PlayStation y PC) y en ocasiones mete elementos tridimensionales con cambios de plano y perspectiva, lo que ayuda a mejorar la variedad del juego.

El arma principal de Hércules es una espada que, además de un uso normal, permite utilizar el «Don de los Dioses» para realizar ataques especiales: bolas de fuego, bombas de sonido y rayos, siempre y cuando encontremos los power ups correspondientes. De igual manera, podemos encontrar figuras de Hércules que le permitirán recuperar su barra de vida y cascos que le concederán invencibilidad durante unos segundos. Otros elementos a encontrar son las letras que componen el nombre de Hércules y que, de hacerlo, permiten pasar directamente al siguiente nivel y unos jarrones que esconden el password para ir directamente al nivel actual desde el menú principal en futuras partidas. Al final de cada nivel nos encontraremos con un jefe final que tendrá un patrón especial para ser derrotado.

Gráficamente, el juego mezcla los sprites 2D con elementos 3D construidos a base de polígonos, lo que permitía aumentar las posibilidades sin perder el espíritu de los plataformas clásicos de Disney. Esto le da un estilo visual muy particular a este juego que sorprendió mucho en su época pero que a día de hoy envejece peor que un juego realizado íntegramente de forma bidimensional.

Esta dualidad fue la que más polémica generó en su momento en la prensa especializada. Si bien muchos críticos aplaudieron la conservación del espíritu de los videojuegos de Disney precedentes, no fueron pocos los que consideraban que el cambio de generación requería de una renovación dentro del género y un mayor aprovechamiento de las posibilidades 3D de las máquinas. No obstante, la recepción del público fue positiva de forma general y en 1998 llevaba 15 millones de copias vendidas en la Unión Europea.

En este vídeo podéis ver cómo es el juego:

Análisis: Plaque Attack (Atari 2600) [Bonus Stage Magazine] [Leer]


PLAQUE ATTACK por Skullo Este comentario proviene de la revista Bonus Stage Magazine número 49 (Especial Superman) Título: Plaque Attack Plataforma: Atari 2600 Número de Jugadores: 1 o 2 Género: Disparos Desarrolladora:Activision (Steve Cartwright) Año: 1983 Son muchos, muchísimos los juegos de Atari 2600 del género de matamarcianos, así que es bastante fácil encontrar juegos […]

Joystick Toshiba HX-J400 (Toshiba Corporation). [Retro Ordenadores Orty] [Leer]


Nuevo en la colección: Joystick Toshiba HX-J400 (Toshiba Corporation). Controlador de juegos fabricado en Japón por la empresa Toshiba Corporation (1939). La empresa japonesa está especializada, entre otras actividades, en la fabricación de equipamiento industrial, electrodomésticos y productos electrónicos de consumo (entre ellos los ordenadores personales). En la década de 1980 fabricó varias series de ordenadores MSX y MSX2 y, en la actualidad, ocupa el quinto lugar (a nivel mundial) en la venta de ordenadores portátiles. El Joystick Toshiba HX-J400 era un controlador analógico con conector de 9 pines (DB9) y dos pulsadores de disparo, diseñado especialmente para utilizar en los ordenadores MSX y otros ordenadores compatibles (los conectores de los ordenadores MSX, los de Amstrad y los compatibles de Thomson, tenían la misma configuración). En la parte superior tenía serigrafiados el nombre de la empresa (TOSHIBA) y el modelo (JOYSTICK HX-J400).


Un pulsador de disparo estaba situado en la parte superior de la palanca y el otro en el lateral izquierdo.