Historial de desarrollo de Asalto y castigo [en SuperBASIC, para QDOS y SMSQ/E]
Descripción del contenido de la página
Historial de desarrollo de la versión de la aventura de texto Asalto y castigo [en SuperBASIC, para QDOS y SMSQ/E].
En la mayoría de los proyectos suelo escribir los cambios más importantes realizados en el código fuente en cada sesión de trabajo. Esto me sirve para rastrear posibles errores o identificar el contenido de las copias de seguridad fechadas. Además la fecha forma siempre parte del número de versión del programa, de modo que el historial de desarrollo sirve también como referencia de las novedades de cada versión.
2011-03-31
De las versiones del programa original elijo como punto de partida la de Blassic, aunque también uso los listados de las versiones en Sinclair BASIC (un poco más limitada que las otras dos) y en Locomotive BASIC, para consultar posibles dudas.
El código fuente necesita pocas modificaciones para que el intérprete de SuperBASIC lo acepte. Estas son las primeras:
- Sustituir
pen
porink
. - Crear una función
left$()
. - Crear una función
mid$()
. - Crear una función
right$()
. - Cambiarle el nombre a la matriz
n()
porque en varios puntos del programa se usa la variablen
y SuperBASIC no lo permite. - Sustituir
asc()
porcode()
. - Sustituir
+
por&
cuando sirva para unir cadenas. - Añadir el segundo parámetro (la longitud máxima) a todas las matrices de texto:
h$()
,a$()
,o$()
yn$()
Y algunos cambios estéticos:
- Crear un procedimiento para la impresión justificada de textos (que en SuperBASIC es muy fácil gracias al separador de impresión «!») y puentear la rutina Format de la línea 9850.
- Sustituir los números usados como colores en
ink
ypaper
por variables con el nombre correspondiente de los colores (en la tabla de Blassic, que es la de CPC). - Crear un procedimiento
init_ql
para iniciar el modo 8 de la QL y crear variables globales con los nombres de los colores originales y asignarles los valores de QL más parecidos. - Cambiar la coma del
input
principal por un punto y coma.
2011-04-04
- Quitadas las nuevas funciones de partición de cadenas en favor del sistema original de SuperBASIC.
- Corregido un error de paréntesis, introducido por mí, que impedía que el intérprete entendiera ciertas acciones.
- Cambiadas todas la llamadas a las rutinas de impresión de texto por los procedimientos equivalentes
narrate
yspeak
. - Renombradas las primeras variables y matrices, para hacer más legible el código y facilitar su adaptación.
- Convertidas en procedimientos las rutinas «mirar», borrar pantalla, «puntos», «pausa»... y muchas más.
- Agrupadas las rutinas de lectura de
DATA
en un solo procedimiento separado de la escena de presentación. - Detectado un posible fallo en el original: Parece que el texto «Todos se apartan y permiten ahora el paso al este.» no se imprime nunca.
- Errata en el original: en el texto «Los sajones te capturan. Su general, sonriendo ampliamente, dice: 'bien, bien'. Del gran Ulfius podremos sacar una buena ventaja.» las comillas interiores son incorrectas. Separación del texto original en partes.
2011-04-05
- Todas las acciones fueron convertidas en procedimientos.
- Las matrices y variables relacionadas fueron renombradas.
- No quedó un solo
GOSUB
por fin. - Errata en el texto original: «ídolo» está en mayúsculas en la descripción.
- No quedó tampoco un solo
GOTO
por fin. - Independizadas las acciones de nadar y abrir en sus propios procedimientos; eran las únicas acciones complejas que estaban en la estructura de selección de acción.
- Detectado un posible fallo en el original: Parece que la condición que hace imprimirse el texto «En cualquier caso, no con las manos desnudas.» no se actualiza en la rutina, y rompe la secuencia de comprobaciones, basadas en el objeto de la frase.
- Renombradas
uno
yotro
comoobject
ycomplement
.
2011-04-06
- Modificado el formato de datos de acciones y verbos.
- Terminado el nuevo analizador, mucho más sencillo.
- Ventanas propias, de 512x256 o de 800x600, centradas en la pantalla.
- Instalacción de la fuente ISO. Más textos castellanizados.
do_action
recibe ahora la acción como parámetro.- Rutina a medida para entrada de textos ISO, basada en la que estoy escribiendo para la aventura CE4.
- Arreglo del procedimiento de conversión a mayúsculas de caracteres ISO, que fallaba en QDOS y Minerva.
- Reescrito el procedimiento
action_break
con una esctructuraSELect
en lugar de losIF
originales, para hacerla más legible. Era la última acción que quedaba por organizar de esta forma. - Independizadas en su propios procedimientos las últimas tres acciones que quedaban dentro del bucle de selección:
action_help
,action_examine
yaction_end
. - Retocados los
IF
del procedimientoplot
para hacerlo más legible: aún no está claro si merecerá la pena usar una estructuraSELect
.
2011-04-07
- La función
is_here()
se convierte enis_accessible()
y se subdivide en dos más específicas:is_here()
yhave()
. - Creados identificadores de habitantes, para hacer más legible el código.
- Creados la función
vanished
y el procedimientovanish
para hacer más legible el código. - Separada la primera dimensión de la matriz
thing_data
con el nombre de location(), para hacer más legible el código. También el escenario del protagonista se guarda en esa matriz a partir de ahora, para unificar la sintaxis de las expresiones. - Se modifica la descripción del tronco cuando ha sido afilado.
- Eliminado el objeto ficticio "amorfa", usado para simular la antorcha encendida. Ahora se usa el mismo método que con el tronco: un indicador y un cambio de descripción, más sencillo.
- Añadido: La acción de meter el tronco afilado en las rocas tiene el mismo efecto que golpearlas con él.
- Corregido error mío en la condición para abrir la puerta.
- Simplificada la selección de herramienta por defecto en
action_break
(se usa la espada si está presente, no hace falta más) y unificados los mensajes de error cuando no ha complemento. - Unificados los usos de los procedimientos
short_pause
yend_of_scene
, y los borrados de pantalla tras este último. - Creada la función
is_person
, para hacer el procedimiento de listado de objetos presentes más legible.
2011-04-08
- Añadidos nuevos sinónimos, verbos y nombres.
- Completada la función
iso_input$
con las funciones de movimiento a comienzo y final de línea; movimiento por palabras; y borrado hacia adelante. - Juntadas las
DATA
de las cosas (localización, tipo y descripciones) y precedida cada una por su identificador. Así se pueden poner en cualquier orden si fuera conveniente, y también se facilita la comprensión del listado. - Creado el objeto candado, que ya existía pero solo virtualmente. Así se evita el mensaje de error al intentar examinarlo. Su descripción cambia, como la de la puerta, tras abrir esta.
- Creados identificadores para las seis direcciones. Así se hace más claro el código. Sus valores son 0-5 en lugar de 1-6 (en SuperBASIC la primera dimensión de las matrices es la 0).
- Indepenzido el código de apertura de la puerta para poder ser llamado también desde la acción de meter (llave en candado).
- Retocada la función
iso_input
y sus auxiliares para funcionar en SuperBASIC (SBASIC es más permisivo con la división de cadenas). - Utilizada la función
INARRAY%
de la extensión DIY Toolkit para buscar los verbos y los nombres. La búsqueda en bruto original era demasiado lenta a la velocidad de la QL original. - Retocadas un par de acciones que usaban
SELect ON location(ulfius)
: SuperBASIC no permite elementos de matriz como selectores. - Para terner más opciones de presentación,
action_help
imprime ahora el texto de ayuda en lugar de volcar directamente el contenido de una variable. En el futuro podría incluirse algo de ayuda contextual. - Cambiado el nombre de la matriz
thing_data
porthing_type
, más fácil de entender.
2011-04-09
La versión actual del analizador fue creada para aceptar textos con cualquier número de espacios en cualquier posición:
deffn parser(command$)
loc first_letter,last_letter,command_len
let first_letter=1
let last_letter=1
let command$=command$&" "
let command_len=len(command$)
let action=false
let object=false
let complement=false
rep find_word
if first_letter>=command_len:exit find_word
rep find_first_letter
if command$(first_letter)<>" "
exit find_first_letter
endif
let first_letter=first_letter+1
endrep find_first_letter
let last_letter=first_letter
rep find_last_letter
if command$(last_letter+1)=" "
exit find_last_letter
endif
let last_letter=last_letter+1
endrep find_last_letter
parse_word command$(first_letter to last_letter)
let first_letter=last_letter+2
endrep find_word
ret syntax_is_fine
enddef
Pero dado que la función iso_input$
impide ya escribir espacios al inicio del texto, o más de dos seguidos en cualquier otro lugar, el análisis del texto puede ser más sencillo y rápido:
deffn parser(command$)
loc next_space,command_len
if command$(len(command$))<>" ":let command$=command$&" "
let command_len=len(command$)
let action=false
let object=false
let complement=false
rep find_word
let next_space=" " instr command$
parse_word command$(1 to next_space-1)
if next_space=len(command$):exit find_word
let command$=command$(next_space+1 to)
endrep find_word
ret syntax_is_fine
enddef
- El borrado de la línea en
show_input
se hace ahora más rápida y sencillamente concls #tw,4
en lugar de imprimiendo espacios. - Corregida la impresión de un espacio en
iso_input
: no estaba actualizada y solo funcionaba bien con espacios añadidos al final del texto. - Todas las funciones de edición de la línea de entrada tienen ya el pitido de error (que podrá desactivarse).
- El escenario actual se guarda ahora en
current_location
en lugar de enlocation(ulfius)
. Así se evita usar variables locales intermedias para las estructurasSELect
. - Añadida a la acción abrir la comprobación de que el objeto sea el adecuado, pues faltaba.
- Reconvertida la función
parser
en el procedimientocommand
, que ahora se ocupa de todo: llama aaccept$
, comprueba la validez del comando y si procede llama a la acción correspondiente. - La función
iso_input$
se hace más independiente: no recibe el pronto como parámetro, sino que es la función superioraccept$
la que lo imprime anticipadamente.iso_input
recibe como parámetro el canal a usar y la longitud máxima del texto; si esta es cero, la calcula a partir de los datos de la ventana. Esto permite usariso_input
en cualquier contexto (aunque en este programa no es necesario).
2011-04-11
- Renombrado
cls_
comoclear_screen
. - Pequeños retoques en estructuras de control y textos.
2011-04-20
- Variable
version$
, inicializada en la cabecera y usada enabout
. - Variable
mistype_bell_active
creada e inicializada. - Función
lines_between()
para calcular conlnum()
el número de líneas de una zona del programa, y con ello el número de datos en líneasDATA
. De esta forma se facilita añadir nuevos datos.
2011-04-21
- Añadido a la función
iso_input$()
el control de la (des)activación del pitido de error de tecleo (con Ctrl+B). - Reformado el fichero boot: usa las líneas a partir de la 32000; usa
MRUN
para cargar después el programa principal (evitando así borrar la pantalla) y lo arranca con unGOTO 100
. - Añadido un mensaje de espera en el procedimiento
game_init
, pues la preparación de los datos puede llevar tiempo con la velocidad de la máquina original. La posición previa del cursor se restaura tras borrar el mensaje de espera. - En Q-emuLator, la carga del programa tarda 147 segundos con la velocidad de la QL original; 24 segundos con la velocidad de la Gold Card y 2 segundos a la máxima velocidad posible en mi Asus Eee 4G (en Debian con Wine).
- Añadida una pantalla de presentación para el formato de pantalla original (512x256).
- Creadas las variables para identificar las acciones y su sintaxis.
- Separadas en diferentes listas de datos las acciones y su sintaxis de los verbos.
- Empezada la distinción de colores en los modos de mayor resolución.
2011-04-23
- Completada la función
iso_upper()
con todos los caracteres posibles, aunque realmente sólo los caracteres ASCII son necesarios en el programa. - Escritos todos los comentarios tanto en castellano como en inglés.
2011-04-24
- Corregida y completada la definición de colores en modos QL y PAL.
- Añadido
_error
(comando de MegaToolkit análogo aert
de Hot Key System) trasfopen
, para detectar posibles errores.
2011-04-25
- Los procedimientos de inicialización del sistema y la pantalla son movidos al fichero de arranque boot.
- Problema: Parece que en Q-emuLator, la función
DMODE
de la extensión Display Toolkit no es reconocida antes de hacerNEW
, lo que la hace inútil.
2011-04-29
- Solucionado el problema de Display Toolkit, aunque aún sin explicación lógica: reorganizando las líneas del fichero boot.
- Escrito el programa ayc2media_bas para empaquetar el programa en los formatos WIN e IMG. Escrito también ayc2media.sh (en Bash para Debian), para hacer lo mismo con los formatos ZIP y QLPAK.
2011-05-03
- Simplificada, en el fichero boot, la función
proc_device$
con el uso deftest
en lugar de una función propia.
2011-05-13
- Corregido error en la rutina de entrada de textos: el cursor no avanzaba si se escribía en medio de la frase.
- Ampliada la rutina de entrada de textos con los atajos de teclado para borrar la línea hasta el principio o hasta el final.
- Modificada en el fichero boot la carga de la extensión
inarray%
para forzar que las búsquedas sean estrictas, sin distinguir minúsculas de mayúsculas ni números. Esto es necesario para evitar posibles falsas equivalencias entre el juego de caracteres de QL y el juego ISO 8859-1 usado por el programa.
2011-05-14
- Implementado el tabulador en el editor de línea, para avanzar o retroceder ocho posiciones.
2011-05-24
- Algunos sinónimos de acciones más.
- Retoques en algunos comentarios.
2011-05-27
- Completados los comentarios bilingües que faltaban.
- Comentarios en la mayoría de procedimientos y funciones del fichero de arranque.
- Primera versión «B» (beta), lista para publicar.
- Corregido un error de encuadre en la pantalla de presentación.
2011-05-29
- Programa publicado.
- Dos erratas corregidas en los comentarios del código fuente, y dos sinónimos nuevos añadidos al vocabulario. (Los ficheros descargables no son actualizados aún).
2011-07-05
- Correcciones en un par de comentarios del código.
2011-07-09
- Corrección de una errata en la descripción del escenario de la explanada. (Los ficheros descargables no son actualizados aún).
2011-07-11
- Corrección de la cita de las palabras del valido al final del juego. Faltaban las comillas interiores.
2011-07-12
Detectado un fallo de formateo en la impresión de diálogos: el procedimiento speak
comprueba si el texto tiene una comilla de cierre y supone que entonces el texto solo necesita la comilla de apertura, pero esto es cierto solo cuando la aclaración está al final del discurso, no en medio (como es el caso de las palabras del valido):
if r_quote$ instr quote$
tell l_quote$"e$
else
let last=len(quote$)
if quote$(last)="." and quote$(last-1)<>"."
tell l_quote$"e$(1 to last-1)&r_quote$&"."
else
tell l_quote$"e$&r_quote$
endif
endif
La solución es comprobar que además no hay una comilla de cierre:
if r_quote$ instr quote$ and not l_quote$ instr quote$
tell l_quote$"e$
else
2011-07-13
Sinómimo para «capa»: «lana».
2011-07-17
Error corregido: el mensaje «Tus hombres luchan con denuedo contra los sajones.» quedaba fuera del flujo porque la condición comprobada inmediatamente antes en el procedimiento plot
, la de la persecución de los sajones, salía del procedimiento. Ahora el mensaje se comprueba dentro de la condición de la persecución.
Sinónimos adicionales para la acción de «nadar»: «bañarte» y «zambullirte».
2011-08-13
Errata corregida en un comentario del código.
2016-01-20
Errata corregida en un comentario del programa lanzador.