<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Knight Lore 20XX: utilizando tcnicas de gr cos por ordenador para llevar un juego clsico a la tecnologa moderna</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Ricard Galvany</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Gustavo Patow</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>ViRVIG-UdG</string-name>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Spain</string-name>
        </contrib>
      </contrib-group>
      <abstract>
        <p>Resumen En muchos aspectos, los juegos de ordenador desarrollados durante la decada de los 80 son una parte fundamental de la historia de los juegos modernos, ya que establecieron las bases de lo que actualmente entendemos por entretenimiento electronico. Sin embargo, la tecnolog a utilizada para esos juegos se han vuelto obsoleta. A pesar de ello, cuando se juega de nuevo a unos de estos clasicos, probablemente a traves de un emulador, la experiencia no esta a la par con los estandares modernos. Por esta razon hemos decidido desarrollar Knight Lore 20XX, como un experimento de la utilizacion tecnicas de informatica gra ca para traer un juego clasico de los an~os 80 a la tecnolog a moderna. Este art culo busca informar acerca de la experiencia, los problemas encontrados y las soluciones desarrolladas. Mientras que la naturaleza simple del juego original preve una cierta estetica en s misma, creemos que nuestro metodo puede producir un juego en 3D convincente que captura de alguna forma el encanto del original, y que podr a ser utilizado para actualizar cualquier otro juego clasico.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        El objetivo de este proyecto fue desarrollar el remake de un juego
clasico del ZX-Spectrum llamado Knight Lore. Para conseguir resultados
lo mas cercanos al juego original, se ha optado por utilizar un nuevo
enfoque donde, en lugar de reconstruir de nuevo el juego desde cero,
queremos aprovechar al maximo el original. Dada que este funciona sobre
los desaparecidos ordenadores Spectrum, nos vemos forzados a trabajar
sobre un emulador. La idea principal fue realizar la ingenier a inversa
del juego para posteriormente desviar el ujo de datos en el momento
de generar las imagenes, utilizando nuestros algoritmos 3D para crear la
escena a partir de los datos generados por el propio juego. De esta forma
la jugabilidad permanecera intacta, solo actualizaremos los gra cos. El
motivo principal para escoger el juego Knight Lore es que fue realizado
con una tecnica pseudo 3D (llamada tecnica Filmation [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ]), que permitie
una reconstruccion parcial de la escena.
2.
      </p>
    </sec>
    <sec id="sec-2">
      <title>Antecedentes</title>
      <p>
        Pixel Art es una forma de arte digital donde los detalles en la imagen
son representado a nivel de p xel. Los gra cos en practicamente todos los
ordenadores y juegos de v deo antes de mediados de la decada de los 90
consist an, sobre todo, en imagenes Pixel Art. Estos videojuegos siguen
siendo disfrutado hoy en d a, gracias a los numerosos emuladores que se
han desarrollado para reemplazar el hardware que se volvio obsoleto hace
mucho tiempo. En dicha tecnica, el hecho de que cada p xel fuese colocado
manualmente permit a alcanzar un maximo de expresion y signi cado por
cada p xel. Kopf y Lichinsky [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] propusieron un metodo para producir arte
vectorial convincente a partir de imagenes en Pixel Art generadas con un
emulador, de manera que su algoritmo se las arregla para capturar algunas
de las caracter sticas y preservar el encanto del original. Otro ejemplo
es el trabajo de Thibeault [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ], que busca reconocer elementos de pixel
art, reemplazandolos dinamicamente por imagenes de nueva creacion. La
escena retro"tambien ha desarrollado interesantes tecnicas con el mismo
objetivo, como los packs de texturas de alta resolucion desarrollados para
la emulacion de la Nintendo 64 [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
3.
      </p>
    </sec>
    <sec id="sec-3">
      <title>KnightLore</title>
      <p>Knight Lore fue un juego creado por la empresa Ultimate Play The
Game en 1984. El videojuego fue desarrollado por Tim Stamper y Chris
Stamper para ZX Spectrum, Amstrad CPC y MSX. En el, el jugador
debe conseguir los ingredientes de una pocion repartidos en un castillo lleno
de trampas y entregarselos a un mago para que lo libre de la maldicion
que transforma al personaje en lobo por la noche. El juego se trata de
un clasico juego de plataformas, su principal novedad reside en el entorno
gra co, que utiliza perspectiva isometrica que permite no solo moverse en
tres dimensiones, sino tambien interaccionar con objetos mediante una
f sica sencilla pero efectiva. El motor utilizado llevo el nombre de
Filmation y se convirtio en la marca principal de la casa.
3.1.</p>
      <sec id="sec-3-1">
        <title>Datos estaticos del Knight Lore</title>
        <p>Mapa: Los lugares de juego se juega en una cuadr cula de 16 16. Ver
Figura 1, izquierda. La direccion de movimiento se calcula de forma impl
cita mediante la adicion al codigo de ubicacion de un valor jo dependiendo
de la direccion (16 norte, -16 sur, -1 oeste, 1 este). Ver Figura 1, derecha.
Los datos de las habitaciones (solo las utilizadas) se almacenan en una
lista secuencial de habitaciones. Para localizar una habitacion se debe
realizar una busqueda iterativa por dicha lista.</p>
        <p>Figura 1. Izquierda: Mapa del juego. Derecha: Orientaciones en el juego.
Habitaciones: Para cada entrada de la lista de habitaciones, el primer
byte representa el identi cador (numero) y el segundo es el taman~o de
los datos de la habitacion. A continuacion, cada entrada almacena otros
datos como las dimensiones y el color, el codigo de las paredes, y un
listado de los objetos contenidos en la habitacion. Ver Figura 2.
Figura 2. Izquierda: Pantalla del juego con sus elementos identi cados. Derecha:
Fondos de una habitacion (0Eh)
Fondos A continuacion, se pasa a leer los datos de los fondos, donde cada
byte representa el identi cador de un fondo hasta que aparezca uno con
valor F F h. El byte con ese valor simplemente determina que empieza la
seccion de los objetos.</p>
        <p>Objetos: Por ultimo, los datos de objetos estan codi cados en una lista
que contiene, para cada uno, su identi cador y numero de instancias,
seguido por la informacion de las posiciones de cada una. Este resultado
puede verse en la gura 3, izquierda. El estado de la misma habitacion,
unos segundos mas tarde, se encuentra en la parte derecha de la misma
gura, lo que nos permite ver que el estado dinamico no puede capturarse
de estos datos.</p>
        <p>Figura 3. Una habitacion al momento de ser inicializada y unos segundos desues.
3.2.</p>
      </sec>
      <sec id="sec-3-2">
        <title>Habitaciones en la memoria de trabajo</title>
        <p>El juego utiliza un espacio de memoria llamado memoria de trabajo
(scratch mem, que esta situada entre las direcciones de memoria 5BA0h
y 6107h) y es la que re eja los datos dinamicos de las localizaciones.
Estudiando el codigo fuente del juego desensamblado, observamos la
funcion llamada RetrieveScreen. Dicha funcion, basciamente, itera sobre la
lista de habitaciones buscando la que se necesita en cada momento, y
descomprime sus datos de localizacion, fondo y objetos en memoria de
trabajo.</p>
        <p>Fondos: RetrieveScreen obtiene los fondos de las habitaciones indexando
el codigo obtenido en una tabla alamacenada de forma estatica a partir
de la direccion 6CE2h, que permite obtener la posicion de los datos de
un fondo simplemente an~adiendo a una direccion base el valor de cada
fondo. Ver Figura 4. Los datos de esta forma indexados nos dan el ID
del sprite ultilizado, sus coordenadas (x; y; z) en el mundo, as como su
ancho, alto y largo.</p>
        <p>Figura 4. Sprites en el juego. formacion de la imagen del arco este. Se puede observar
claramente como la imagen nal es el resultado de componer dos sprites mas simples.
Objetos: A continuacion, la funcion RetrieveScreen itera sobre los objetos
en la habitacion para recuperar su informacion 3D y su representacion en
espacio de imagen. Para ello se utiliza otra tabla de indirecciones
posicionada en 6BD1h, y se le suma el ID del objeto a escoger multiplicado
por 2 (la cantidad de bytes que ocupa una direccion de memoria en el
ZX Spectrum). Por ejemplo, el fuego tiene identi cador 0Ah, lo que nos
conduce a la posicion 6BE9h, donde obtendremos las coordenadas x; y; z,
as como una referencia a su sprite y si debe dibujarse invertido (modo
espejo) o no: cabe recordar que el ZXSpectrum era un ordenador muy
limitado en cuanto a memoria. Hay un serie de objetos (los que se
mueven de manera regular, como por ejemplo los guardias o el fuego) que
requieren cambioar de posicion en funcion del movimiento que realizan.
Esta informacion tambien se encuentra especi cada en estos bytes, que
basicamente son ags que determinan si alguna de las coordenadas
requiere de la correccion. Cada instancia de un objeto tendra una entrada
independiente en la zona de trabajo.</p>
        <p>
          Resolucion 3D alta y baja: Aunque las coordenados de los fondos, objetos
y el personaje principal inicialmente estuvieran en 3D de baja resolucion
(low), en la memoria de trabajo se almacenaban en 3D de alta resolucion
(high). Utilizando el siguiente sistema de ecuaciones, podemos pasar de
3D Low a 3D High y viceversa, que era lo que nos interesaba, pues la
informacion dinamica trabajaba en 3D de alta resolucion [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ]:
XH = 16XL + 8Xs + 72
YH = 16YL + 8Ys + 72
        </p>
        <p>ZH = 12ZL + 4Zs + ScreenZ
donde XL; YL; ZL son las coordenadas en 3D de baja resolucion (le das
de la informacion estatica del juego), Xs; Ys; Zs son valores que forman
parte de la informacion que de ne los sprites y que permiten trabajar con
los objetos que se desplazan solos. En funcion de cada objeto tienen un
valor u otro. Finalmente ScreenZ es una constante que siempre vale 128.
Ver la Figura 5.</p>
        <p>Figura 5. Resultado de cambiar las coordenadas de baja resolucion de un objeto.
Personaje Principal: Para obtener informacion de como se almacena al
personaje principal, realizamos una comparacion de la memoria de
trabajo variando solo la posicion del mismo y dejando jos todos los otros
parametros (anulando las respectivas funciones de evolucion). Ver la
Figura 6, izquierda. Las coordenadas del personaje estan separadas en dos
bloques: las situadas en las posiciones de memoria 5C09h, 5C0Ah y 5C0Bh
representan las coordenadas x; y; z de la posicion cuerpo del personaje
principal, y las situadas en las posiciones de memoria 5C 20h, 5C2Ah y
5C2Bh, representa la posicion de la cabeza. Ver Figura 6, derecha. La
representacion de los personajes en el juego en general esta formada por
dos bloques, para as poder aplicar diferentes animaciones de manera
separada. Para el personaje principal, los bytes situados en la direcciones
5C41h y 5C45h indican los sprites del personaje a utilizar. Para acabar de
determinar la orientacion, se utilizan los bytes de las direcciones 5C0F h
y 5C2F h, que sirven para diferenciar los sprites que tienen el mismo
identi cador pero que el motor gra co invierte, aplicando una operacion de
espejo.</p>
        <p>Figura 6. Coordenadas (izquierda )y sprites (derecha) que forman el personaje
principal.
4.</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Implementacion del Knight Lore 20XX</title>
      <p>Llegado este punto nos surgio una problematica al pasar el control al
nuevo entorno 3D. Por de nicion, OpenGL es una maquina de estados,
y una vez se le ha pasado el control, itera inde nidamente hasta que se
termina el programa o se le obliga a terminar. Esto hac a que el emulador
se quedara \estancado" ejecutando el entorno 3D. Para ello, en lugar
de ejecutar la funcion que realiza una iteracion del emulador, y luego
ejecutar la que genera el entorno 3D, se opto por conceder el control
absoluto al entorno 3D y mediante funciones propias de OpenGL que
permiten especi car que hacer en per odos de inactividad, ir concediendo
iteraciones a la funcion de emulacion. Vemos que estas dos disposiciones
hacen que se vaya dibujando el nuevo entorno cuando es necesario, y a la
vez se ejecuta el codigo de emulador.</p>
      <p>Para adquirir los datos del juego, primero se creo una funcion que
adquiriera toda la informacion geometrica que se requiriese para la
recreacion del juego, a partir de la informacion almacenada en la
informacion inicial estatica que de ne las localizaciones, la memoria de trabajo,
la tabla de los datos de los fondos, y labla de los datos de los objetos.
Fondos Las paredes de cada habitacion se dibujaron utilizando las
texturas del juego original. El proceso comprendio la captura de cada sprite
(ver Figura 7), que conformaba cada pared para su posterior
almacenamiento en un chero gra co. La funcion de dibujado de fondos examina
los datos dinamicos de la habitacion, para obtener los identi cadores de
los sprites que formaran parte de la pared. Despues, carga los cheros
que corresponden a los sprites de la pared y los coloca en funcion de su
posicion en el nuevo entorno. Hay que tener en cuenta que las texturas
capturadas del juego original presentan una distorsion en perspectiva
ortogra ca, pero que se soluciono gracias a que, mediante OpenGL, a la hora
de aplicar una textura a un objeto, podemos corregir su posicionamiento
mediante la tecnica llamada dewarping. La tecnica dewarping elige una
serie de puntos, que se pasan como coordenadas de textura a OpenGL.
Entonces este ultimo realiza las correcciones necesarias para aplicar la
textura para su correcta visualizacion. Conceptualmente se muestra en la
Figura 7. El resto de los fondos (mayoritariamente puertas) se dibujaron
como cualquier otro objeto, utilizando geometr a modelada al efecto.
Figura 7. Izquierda: Diferentes sprites para las paredes. Derecha: la tecnica dewarping.
Objetos En nuestro sistema, todos los objetos son dibujados mediante
primitivas OpenGl. Ver la Figura [?]. La funcion que se encarga de
dibujarlos es llamada por la funcion de principal tantas veces como objetos
dispone la localizacion. Cada llamada incluye los argumentos necesarios
que describen el objeto. En funcion del identi cador que recibe,
muestra unas primitivas u otras. Si hay algun objeto no de nido, entonces se
dibuja el objeto por defecto, que en nuestro caso es una pequen~a esfera.</p>
      <p>Hay que destacar que, aunque hay varios objetos que comparten un
aspecto visual, de caras a la interaccion en el juego se comportan de
diferente manera, e incluso no disponen del mismo identi cador de sprite. Es
el caso de un objeto muy comun, el bloque, el cual dispone de diferentes
entidades (bloque jo, bloque que desaparece al ser pisado, bloque con
movimiento), que internamente el juego trata de manera diferente, pero
visualmente se representan igual. Los objetos que disponen de animacion
(pelota, fuego, soldado, etc.) requieren de diferentes sprites para
repre</p>
      <p>Figura 8. Ejemplo de la visualizacion resultante con nuestro algoritmo.
sentarla. Tambien en este caso es algo transparente para el nuevo entorno
del juego, ya que el juego original va modi cando la memoria de trabajo
en funcion del sprite que requiere cada objeto animado y de su estado.
Personaje Principal La funcion que dibuja el personaje principal,
primeramente obtiene las coordenadas (x; y; z) situadas en las posiciones de
memoria 5C09h, 5C0Ah y 5C0Bh (ver seccion 3.2). Seguidamente
convierte estos valores de coordenadas 3D High al entorno OpenGL. Una vez
conocida la posicion, se debe deducir el estado del personaje (hombre o
lobo) y su orientacion. Consultando la posicion de memoria 5C41h
obtendremos el identi cador del sprite del cuerpo del personaje, y con ello
su estado y orientacion. Para terminar de saberla, deberemos consultar la
posicion de memoria 5C0F h, que nos dice si se debe hacer una operacion
de espejo o no. Una vez adquiridos los datos del personaje para dibujarlo,
aplicamos una rotacion, posteriormente una traslacion y luego utilizamos
varias primitivas de OpenGL para nalmente dibujar el personaje. Ver
Figura 9.</p>
    </sec>
    <sec id="sec-5">
      <title>Resultados</title>
      <p>El resultado nal consta de un nuevo entorno, como podemos
observar en la gura 10, abajo. La gura 10, arriba, muestra una secuencia del
movimiento de un balon botando. Tambien dispone de la opcion de
visualizar el juego en 3D desde diferentes perspectivas y un mejorado aspecto
visual.</p>
      <p>Figura 9. Personaje principal en el viejo y nuevo contexto.</p>
      <p>Dadas las caracter sticas del juego original, su ejecucion se realiza
completamente en un emulador de ZXSpectrum, lo cual representa un
costo realmente bajo para los estandares actuales. Por lo tanto, el
ordenador dispone de un tiempo considerable que permite no solo visualizar la
escena en 3D (tarea principalmente a cargo de la GPU), si no que permite
el uso de geometr a mucho mas complexa que la utilizada en esta
prueba de concepto, la incorporacion de so sticados efectos de iluminacion, y
practicamente cualquier efecto gra co de un juego actual. Todo esto
puede incluirse sin que ello represente ningun problema para la jugabilidad,
controlada por el codigo original.</p>
      <p>Respecto a los aspectos metodologicos que permitir an replicar este
trabajo para cualquier otro juego, estan limitados por el proceso de
ingenier a inversa, que requiere la localizacion de la memoria de trabajo y
la decodi cacion de la informacion almacenada en ella. La
automatizacion de dicho trabajo ser a de extrema complejidad, i evidentemente debe
incluirse en el conjunto de tareas a considerarse en el trabajo futuro.</p>
    </sec>
    <sec id="sec-6">
      <title>Conclusiones y Trabajo Futuro</title>
      <p>Hemos conseguido desarrollar un remake de un juego clasico del ZX
Spectrum sin reconstruir el juego completamente, sino an~adiendo
funcionalidades para generar un nuevo contexto gra co, simplemente desviando
el ujo gra co e implementandolo nuevamente en un contexto 3D. Para
ello hemos estudiado la arquitectura del ZX Spectrum, hecho uso de la
inFigura 10. Abajo: Diferentes vistas de una habitacion de Knight Lore 20XX y el
original. Arriba: Secuencia de un balon en movimiento en una habitacion.
genier a inversa para descubrir como trabaja el juego, y creado un nuevo
motor de renderizacion basado en elementos geometricos y texturas.</p>
      <p>Respecto a los trabajos futuros a desarrollar, ademas de los ya
mencionados, estos podr an ser dibujar los objetos mediante diferentes tecnicas
apropiadas para representarlos y conseguir un mejor acabado nal de los
mismos; aplicar fuentes de luz para mejorar el aspecto en consonancia a
la tematica del juego; mejorar la tecnica de captura de sprites para que se
obtengan directamente del codigo de juego; y la generalizacion del
codigo para que se adapte a otros juegos que trabajen mediante las mismas
tecnicas.</p>
    </sec>
    <sec id="sec-7">
      <title>Agradecimientos</title>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <surname>Kopf</surname>
            ,
            <given-names>J.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Lischinski</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          :
          <article-title>Depixelizing pixel art</article-title>
          .
          <source>ACM Trans. Graph</source>
          .
          <volume>30</volume>
          (
          <issue>4</issue>
          ),
          <source>99:1{99:8 (Jul</source>
          <year>2011</year>
          ), http://doi.acm.
          <source>org/10</source>
          .1145/2010324.1964994
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <surname>Lazo</surname>
            ,
            <given-names>J.M.:</given-names>
          </string-name>
          <article-title>Iniciacion al sistema lmation</article-title>
          .
          <source>MicroHobby</source>
          <volume>3</volume>
          (
          <issue>97</issue>
          ,
          <fpage>98</fpage>
          , 99 y 100),
          <volume>28</volume>
          {30 (Octubre
          <year>1986</year>
          ), https://archive.org/details/microhobby-magazine
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3. Racketboy:
          <article-title>Enhance n64 graphics with emulation plugins texture packs</article-title>
          . http://www.racketboy.com/retro/nintendo/n64/enhance-n64
          <string-name>
            <surname>-</surname>
          </string-name>
          graphics
          <article-title>-withemulation-plugins-texture-packs</article-title>
          ,
          <source>accessed: 2016-05-26</source>
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <surname>Thibeault</surname>
            ,
            <given-names>C.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Herve</surname>
          </string-name>
          , J.Y.:
          <article-title>Object Detection in Emulated Console Games</article-title>
          . In: Prakash,
          <string-name>
            <surname>E</surname>
          </string-name>
          . (ed.) 8th Annual International Conference on Computer Games, Multimedia and
          <string-name>
            <surname>Allied Technology (CGAT</surname>
          </string-name>
          <year>2015</year>
          ).
          <source>Global Science &amp; Technology Forum (GSTF)</source>
          ,
          <source>Global Science &amp; Technology Forum (GSTF) (Apr</source>
          <year>2015</year>
          ), https://www.dropbox.
          <source>com/s/d25pkg6jai7cvn1/CGAT 2015 Proceedings Paper 8.pdf?dl=0</source>
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <surname>Wild</surname>
            ,
            <given-names>C.</given-names>
          </string-name>
          :
          <article-title>Knight lore data format</article-title>
          . http://www.icemark.com/dataformats/knightlore/index.html, accessed:
          <fpage>2016</fpage>
          -05-26
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>