Inicio > Desarrollo, Tutorial > Hazte un Spectrum (8ª Parte y final)

Hazte un Spectrum (8ª Parte y final)

Todos los componentes están realizados y en su sitio, el código ha ido tomando forma con una maravillosa fluidez y he aprendido lo indecible durante estas breves semanas. Aprovecho que mañana vuelvo a la dura vida cotidiana para cerrar esta serie de artículos – unos remates finales y completar el código fuente.

Hemos llegado al final del camino – unas semanas que me han servido para conocer un poco más uno de los mitos de la informática personal de los años ‘80 y que para mí, hasta hace unas semanas, era casi un completo desconocido. Hemos empezado por diseñar una máquina virtual, ir aprendiendo cómo funcionaban los diferentes componentes de la misma y emulando su comportamiento. Hoy concluye este fascinante viaje. Vamos a divertirnos un poco y darle incluso un aire más “retro” al emulador, aprendiendo de paso cómo aprovechar las capacidades de aceleración hardware de gráficos de WPF.

Vamos a empezar con una herramienta imprescindible para diseñar interfaces de usuario en aplicaciones modernas: Photoshop. Con ella vamos a realizar una capa gráfica (“overlay”) que podremos activar a voluntad para darle ese toque retro, imprescindible para mi: el “efecto TV” o, como me ha dado por llamarlo en el emulador, el “modo Telefunken” (y apuesto a que mi hermano estará de acuerdo conmigo a que el nombre le viene que ni pintado gracias a nuestras experiencias de chavales).

Una nueva herramienta de desarrollo: Photoshop

Comencemos (sorprendentemente) buscando en Google Images por un fondo apropiado. Nada más facil que navegar http://images.google.com y buscar por “TV frame”. Busco un “marco de televisor”, y he escogido el que me ha parecido más simpático, que incluso ya viene con el hueco transparente. Veamos los pasos siguientes, uno a uno:

El primer paso es abrir la imágen que más nos guste en Photoshop y ajustar su tamaño a 640×480. Invocando el menú Image/Image Size podremos ajustarlo. Si habéis cargado la imagen como “Background”, haced doble click sobre ella para convertirla en una capa normal (Layer). Ponedle como nombre “TV Frame” por ejemplo y borrad todo lo que pudiese verse dentro la imagen para que quede transparente: TVLayer-4
Vamos a crear una nueva imagen, con un tamaño algo peculiar: 1 pixel de ancho por 2 de alto. Esta imagen nos servirá como “relleno” para el familiar efecto de las líneas en pantalla TVLayer-1
Tras crear la imagen, seleccionamos la herramienta “lápiz” y rellenamos el pixel de arriba en negro, dejando el pixel de abajo transparente TVLayer-2
Seleccionad la imagen con Ctrl+A y luego Edit/Define Pattern. Yo le puse de nombre “ScanLine”. TVLayer-3
Volved ahora a la imagen principal con nuestro televisor. Añadid una nueva capa y aseguraos que queda debajo del marco del televisor. Ponedle de nombre por ejemplo “Scanlines”: TVLayer-5
Aseguraos que tenéis la capa Scanlines seleccionada y rellenadla con el patrón que diseñamos antes. Pulsad mayúsculas+BackSpace, seleccionad “Pattern” de la lista de opciones y el patrón Scanlines como “Custom Pattern”: TVLayer-6
Ya tenemos nuestro familiar efecto de líneas de televisor… simplemente ajustad la opacidad de la capa “al gusto” (40-60%) TVLayer-7
Agregad una nueva capa al diseño, y colocadla entre el marco del televisor y la capa de líneas. Yo la he llamado “Glare”: TVLayer-8
Seleccionad la capa y empleando la herramienta de selección, dibujad un rectángulo que ocupe más o menos el tercio superior de la pantalla. Luego redondead la selección con la herramienta Select/Modify/Feather y algo así como 25 píxeles: TVLayer-9
Comprobad que vuestros colores son el blanco para la tinta y el negro para el fondo, seleccionad la herramienta de gradientes y en la barra superior escoged la configuración “Foreground to transparent” (esto es, de blanco – nuestro color actual – a transparente). TVLayer-10
Ahora pulsad con el botón más o menos en la zona superior de la selección y arrastradla hasta un poco antes de la zona inferior. Luego ajustad un poco la opacidad de la capa, quizá entre 60-70%: TVLayer-11

Ya tenemos el overlay listo – simplemente guardadlo dentro del proyecto del emulador como PNG de 32 bits (con transparencia!!) y ya podemos importarlo en el proyecto. Para ello pulsad con el botón derecho del ratón sobre el proyecto en el que queráis añadir la imagen y seleccionad “Add/Existing Item”. Buscad la imagen PNG, aceptad el diálogo y aseguraos que en las propiedades de la imagen, la entrada Build Action aparece configurada como “Resource”: el compilador “incrustará” la imagen dentro del binario, permitiéndonos olvidarnos de distribuir los ficheros sueltos junto a la aplicación.

Ahora abrid el archivo MainWindow.xaml, y añadid una nueva imagen justo debajo del control zx:Spectrum:

    <zx:Spectrum x:Name="emulator" Grid.Row="1" />
    <Image x:Name="tvOverlay" Grid.Row="1" Source="/YASS;component/Resources/TVEffect.png" Stretch="Fill" Visibility="Collapsed" />

La propiedad Source especifica la imagen que debe emplear el control, en este caso Source=”/YASS;component/Resources/TVEffect.png”. La primera parte (“/YASS;”) indica el nombre del ensamblado que lleva el archivo, en este caso “YASS.exe” que será el nombre del ejecutable. Lo que sigue es el camino (o “path”) hasta el recurso: en mi caso el archivo se llama “TVEffect.png” y está dentro de la carpeta “Resources” del proyecto. Si no queréis tener que averiguar el camino al archivo, insertad una imagen sin campo “Source” y luego simplemente usad las propiedades del control en Visual Studio. Navegad hasta la propiedad Source en la lista y seleccionad directamente la imagen con el menú desplegable – mucho más fácil que ponerlo a mano y sin errores!!! Fijaos que los dos elementos (el control zx:Spectrum y la imagen “tvOverlay” están situados en la misma celda del Grid que los contiene. El efecto es que la imagen cubrirá permanentemente al control, sin tener que hacer absolutamente nada en código – solo cambiar su visibilidad.

Aprovechad tambien para añadir al menú de la aplicación una entrada para activar o desactivar el “modo Telefunken”:

<Menu>
  ...
  <MenuItem Header="Load tape..." Click="OnSelectTape"/>
  <Separator/>
  <MenuItem x:Name="tvModeMenu" Header="Telefunken mode" Click="OnTVMode" />
  ...
</Menu>

Finalmente, basta con agregar la función “OnTVMode()” al programa, que alternará la visibilidad de la capa:

  private void OnTVMode(object sender, RoutedEventArgs e)
  {
    // Invert visibility of tv overlay
    tvOverlay.Visibility = tvOverlay.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
    tvModeMenu.IsChecked = tvOverlay.Visibility == Visibility.Visible;
  }

Si ejecutamos el emulador y seleccionamos el menú “Telefunken Mode”, el efecto será un emulador incluso más retro:

YASS-OldieLook

El overlay está acelerado por hardware, así que la capa no afecta en lo más mínimo a la velocidad de ejecución del emulador, ni incrementa el consumo de la cpu – la tarjeta gráfica hace todo el trabajo.

Alguna cosita más?

Pues si, un par de cosas que he añadido al código final antes de publicarlo. Lo más significativo es que al seleccionar un archivo de cinta ya no es necesario escribir LOAD “” para iniciar la carga. La solución, rápida y simple: una función que emula la pulsación de las teclas para escribir el comando tras abrir el archivo TAP. Muy simple, pero cumple con su cometido – con la pega de que necesitamos que el Spectrum esté dispuesto a aceptar el comando para que funcione. También encontraréis opciones para parar, arrancar y resetear el emulador – funciones que he empleado para depurar algunas cosas y asegurarme de que no me dejaba nada “tirado” por ahí.

Bueno… creo que eso es todo

El emulador está completo y el viaje ha llegado a su fin. Me he divertido mucho, realmente mucho durante estas semanas y me ha encantado intentar documentar todo el proceso. El emulador que os dejo está lejos de ser completo o de ejecutar “absolutamente todos los programas del Spectrum” – no había tiempo para tanto, siendo más bien mi intención la de ofreceros un tutorial completo sobre cómo desarrollar un emulador “desde cero”, cómo combinar varios lenguajes de programación para obtener los mejores resultados y, sobre todo, mostraros cómo era la informática de los años 80. He intentado mantener el código fuente lo más limpio y estructurado posible y creo que es bastante facil de leer y, sobre todo, ampliar.

Como os decía al principio, hace unas semanas no conocía apenas nada del Sinclair ZX Spectrum, y seguro que algún error habré cometido al documentar o emular alguna funcionalidad – espero que sepáis disculparme y, sobre todo, dejadme saber dónde he metido la pata – quiero seguir aprendiendo!

Mañana me toca volver a los quehaceres diarios, pero esta “retromanía” me sigue afectando… cual podría ser el próximo proyecto?

Enlaces:

Emulador YASS para Windows
Código fuente del Emulador YASS
Código fuente del Emulador YASS – actualizado a VS2015

– Hazte un Spectrum: 1ª Parte, 2ª Parte, 3ª Parte, 4ª Parte, 5ª Parte, 6ª Parte, 7ª Parte, 8ª Parte

Anuncios
Categorías:Desarrollo, Tutorial Etiquetas: , , , , ,
  1. 12/Sep/2012 en 10:20 pm

    Enhorabuena por tu emulador. Es un trabajo de chinos que vale la pena hacer al menos una vez aunque solo sea por lo que se aprende. He descubierto tarde la página, si no te habría dado algún consejo o complementado información. No he podido probar tu emulador todavía porque no uso Windows habitualmente, a ver cómo me las arreglo.

    Ideas acerca de qué puedes hacer ahora tengo como mil, pero te mencionaré un detalle que puede motivarte a seguir en una dirección concreta: con lo que has hecho, funcionarán aproximadamente el 50 o 60% de los programas que existen. Con algunos empujones adicionales, podrías llegar al 95% sin grandes problemas. Los verdaderamente difíciles son el 5% restante, de los cuales hay quizá un 2% verdaderamente desesperantes que son el auténtico reto a lograr.

    Animo, que has empezado muy bien. 🙂

    Saludos
    José Luis

    • 12/Sep/2012 en 10:29 pm

      Muchísimas gracias por tus comentarios. Si, me lo planteé como un emulador “general”, al habérmelo planteado como “proyecto de verano” y, sobre todo, me apetecía documentar la experiencia.

      Me costa que no funcionaran muchas cosas – las que apuran el hardware al limite. Pero conseguí echar a andar un buen montón de juegos que recordaba de jugar en casa de un amigo!! Esa era mi meta. Y el aprendizaje de este mes ha sido genial!

      Un poco mas adelante me gustaría buscar una lista de programas “limite” y qué características hay que emular a la perfección para que funcionen… Y a partir de ahí, pasito a paso!!!

      • 12/Sep/2012 en 10:52 pm

        Pues nada, si algún día te decides, dímelo y te mandaré una lista de programas puñeteros y algunos programas de test que pueden facilitarte la vida a la hora de saber si la emulación es lo bastante buena o no.

        Eso sí, tómatelo con tranquilidad, que llevo 3 años largos con mi emulador y aún no lo he acabado… :-O

  2. jotacepuntomarcos
    14/Sep/2012 en 7:47 am

    Lo único “malo” de ésta apasionante serie de artículos es que me he visto incapaz de absorber ni la cuarta parte de la sabiduría que contiene. Supongo que se convertirá en literatura clásica, de esa a la cual regresas una y otra vez, buscando y encontrando soluciones y, sobre todo, inspiración.

    Legendario.

  3. 15/Ene/2016 en 5:59 pm

    Hola,
    Un trabajo impresionante… Soy aficionado al MSX (comunidadMSX.com) aunque últimamente no actualizo el Blog, pero llevaba mucho tiempo dándole vueltas al tema de hacer un emulador del MSX y estos artículos me los estoy estudiando con todo detalle… (quizás me falten conocimientos tan profundos del C++, pero poco a poco lo voy cogiendo)… Mi pregunta es la siguiente, no consigo compilar de ninguna forma la solución desde Visual Studio 2015… En fin seguramente será torpeza por mi parte pero para poder entender mejor el trabajo sería genial poder tenerlo funcional e ir probando a modificar cosas… es decir, como aprendimos a programar en los ochenta con nuestros ordenadores… ¿Te sería difícil genera y subir una versión para el VS 2015? Te lo agradecería un montón… y MUCHAS GRACIAS por el trabajazo y sobre todo compartir tanta información como en este proyecto… Gracias Mil!!!

    • 16/Ene/2016 en 12:41 pm

      Muchísimas gracias por tu comentario – todo un halago! La verdad es que no creo que me cueste mucho trabajo, así que si me das unos cuantos ratitos (espero que no muchos), actualizo el proyecto a VS2015 y dejo el link por aquí para ti y cualquier otro que quiera seguir con el proyecto. Gracias a ti!

    • 16/Ene/2016 en 1:41 pm

      Ha sido rápido… ha bastado con especificar explícitamente el namespace de la clase array de CLI. Cuando escribí YASS en 2012, sólo existía una (la de CLI). Con las nuevas versiones de C++ ahora tenemos la versión “nativa” (std::array) y el compilador no sabía cual de ellas usar, así que seleccionaba la nativa en lugar de la versión CLI. Basta con añadir el prefijo (cli::array) para evitar el error.

      Para todo aquel que esté interesado, he añadido el enlace a la versión VS2015 del proyecto en los enlaces al final del artículo.

      • 16/Ene/2016 en 9:43 pm

        Hola,
        Ante todos MUCHISIMAS GRACIAS por tu rápida respuesta y el haber subido la versión actualizada para VS2015. Llevo mas de 6 horas seguidas pegado al ordenador mirando y mirando el proyecto YASS. Alucinante, muchas de las cosas que realizas, sobre todo por la simplicidad que aplicas en las solución obtenida a muchos temas… En fin tengo para muchos días para investigar sobre el proyecto y a ver si después consigo actualizar-convertir una versión para MSX que sería lo más… Espero no molestarte mucho, pero ya te iré contando como avanzo y si alguna duda me surge lo mismo abuso de tu amabilidad… Si acudes algún evento retroinformático a ver si nos vemos… Muchas Gracias de nuevo y UN GRAN TRABAJO el hecho con YASS!!!!

      • 16/Ene/2016 en 9:55 pm

        Ha sido un placer. Cuenta conmigo si te puedo echar una mano con tu proyecto (por lo menos tienes una base para el procesador Z80, aunque te toca la parte dura – emular el resto del hardware!!).
        Gracias a ti por interesarte por el proyecto y tus comentarios!!!

  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: