Listados de Asalto y castigo [en SuperBASIC, para QDOS y SMSQ/E]
Descripción del contenido de la página
Listados de la aventura de texto Asalto y castigo [en SuperBASIC, para QDOS y SMSQ/E].
Muestro en esta página independiente los listados de Asalto y castigo [en SuperBASIC, para QDOS y SMSQ/E] para no hacer demasiado larga la página del programa y para que no los lea accidentalmente quien solo esté interesado en descargar el juego y probarlo, pues su lectura revela fácilmente la trama y la solución a los problemas.
Código fuente
Cargador
rem Cargador para "Asalto y castigo"
rem Boot for "Asalto y castigo"
rem Este programa usa varios procedimientos y funciones de las siguientes extensiones de SuperBASIC:
rem This program uses several procedures and functions from the following SuperBASIC extensions:
rem De/From "DIY Toolkit", (C) Simon N. Goodwin:
rem minimum
rem De/From "Display toolkit", (C) Dilwyn Jones:
rem flim_w,flim_h,flim_x,flim_y,dmode
tk2_ext
let dev$=device$("ayc_bas")
lrespr dev$&"ext_display_code":print #0,"Display Toolkit"
lrespr dev$&"ext_megatk_code"
lrespr dev$&"ext_minmax_code":print #0,"DIY Toolkit - minmax"
let a=respr(flen(\dev$&"ext_inarray_code"))
lbytes dev$&"ext_inarray_code",a
poke a+301,0:rem forzar comparaciones exactas / force strict comparations
call a:print #0,"DIY Toolkit - inarray"
init_the_keyboard
init_the_screen
init_the_window
splash_screen
mrun dev$&"ayc_bas"
wipe_the_window
go to 100
deffn device$(file$)
rem Devuelve el primer dispositivo en que se encuentra el fichero dado.
rem Return the first device the given file is found in.
loc dev_offset,number,devs$,dev$
let dev$=""
let devs$="windosflpmdv":rem WIN, DOS, FLP, MDV
if ftest(file$)
for dev_offset=1 to len(devs$) step 3
for number=1 to 8
let dev$=devs$(dev_offset to dev_offset+2)&number&"_"
if not ftest(dev$&file$):exit dev_offset
endfor number
next dev_offset
let dev$=""
endfor dev_offset
endif
ret dev$
enddef
defproc init_the_keyboard
rem Carga la tabla de teclado española para SMSQ si es necesario.
rem If needed, load the Spanish SMSQ keybard table.
loc Spanish
let Spanish=34
if ver$="HBA"
if language<>Spanish
lrespr dev$&"qxl-es_kbt"
kbd_table Spanish
lang_use Spanish
endif
endif
enddef
defproc init_the_screen
rem Inicializa la pantalla, cambiando el modo y la modalidad de color si es necesario.
rem Init the screen. If needed, change its mode and colour scheme.
loc screen_mode
let screen_mode=dmode
sel on screen_mode
=0:mode 8:init_ql_colours
=8:init_ql_colours
=remainder:init_pal_colours
endsel
let scr_w=flim_w(#0)
let scr_h=flim_h(#0)
enddef
defproc init_pal_colours
rem Fija el modo de color PAL y los colores a usar.
rem Set the PAL colour mode and the needed colours.
colour_pal
let black=0
let dark_cyan=7:palette_8 dark_cyan,rgb(0,139,139)
let dark_green=17
let light_grey=12
let light_red=1:palette_8 light_red,rgb(255,51,51)
let yellow=6
enddef
defproc init_ql_colours
rem Fija los colores usados en el modo de color de QL.
rem Set colours used in QL colour mode.
let black=0
let dark_cyan=5
let dark_green=4
let light_grey=7
let light_red=2
let yellow=6
enddef
deffn rgb(red,green,blue)
ret red*65535+green*256+blue
enddef
defproc init_the_window
rem Crea la ventana, hasta un máximo de 800x600.
rem Init the window, maximum size 800x600.
let csize_w=3-(scr_w=512)
let csize_h=scr_w>512
let tw=fopen("con_")
csize #tw,csize_w,csize_h
let tw_w=minimum(800,scr_w)
let tw_h=minimum(600,scr_h)
let tw_x=(scr_w-tw_w)/2
let tw_y=(scr_h-tw_h)/2
window #tw,tw_w,tw_h,tw_x,tw_y
paper #tw,black
ink #tw,light_grey
wipe_the_window
init_the_font
enddef
defproc wipe_the_window
border #tw,0
cls #tw
border #tw,8
enddef
defproc splash_screen
if flim_w(#0)=512 and flim_h(#0)=256
lbytes dev$&"img_ayc8_scr",address(#0)
endif
enddef
defproc init_the_font
loc font_size
let font$=dev$&"iso8859-1_font"
font_size=flen(\font$)
font_address=alchp(font_size)
lbytes font$,font_address
iso_font
enddef
defproc iso_font
fonts font_address
enddef
defproc ql_font
fonts 0
enddef
defproc fonts(font_address)
char_use #tw,font_address,0
enddef
Programa principal
rem Asalto y castigo
rem para QL, en SuperBASIC / for QL, in SuperBASIC
let version$="B-20110711"
rem Copyright (C) 2011 Marcos Cruz (programandala.net)
rem Licencia/License: http://programandala.net/licencia
rem Programa original en / Original program in
rem Sinclar BASIC (Sinclair ZX Spectrum), Locomotive BASIC (Amstrad CPC) y/and Blassic:
rem Copyright (C) 2009 Baltasar el Arquero
rem http://caad.es/baltasarq/
rem --------------------------------------------
rem Notas
rem Notes
rem Este fichero no usa el juego de caracteres de QL sino la codificación estándar ISO 8859-1.
rem This file doesn't use the QL charset but a standard ISO 8859-1 encoding.
rem Este programa usa varios procedimientos y funciones de las siguientes extensiones de SuperBASIC:
rem This program uses several procedures and functions from the following SuperBASIC extensions:
rem De/From "MegaToolkit", (C) 1992 Michael A. Crowe:
rem true,false,char_w,char_x,pos_x,pos_y,lnum
rem De/From "DIY Toolkit", (C) Simon N. Goodwin:
rem inarray%
rem --------------------------------------------
rem Main
main
defproc main
first_time_init
rep game
about
game_init
end_of_scene
intro
action_look
rep your_turn
plot
command
if start_over:exit your_turn
endrep your_turn
endrep game
enddef
rem --------------------------------------------
rem Argumento
rem Plot
defproc plot
rem Comprueba las condiciones de la trama.
rem Check the plot conditions.
if current_location=8 and location_exit(8,north)
let location_exit(8,north)=false
let saxons_follow=1
narrate "Una partida sajona aparece por el este. Para cuando te vuelves al norte, ya no te queda ninguna duda: era una trampa."
short_pause
narrate "En el estrecho paso es posible resistir, aunque por desgracia sus efectivos son muy superiores a los tuyos."
end_of_scene:clear_screen
narrate "Tus oficiales te conminan a huir."
speak "Capturando a un general britano, ganan doblemente."
narrate "Sabes que es cierto, y te duele."
ret
endif
if saxons_follow and current_location<12
let saxons_follow=saxons_follow+1
narrate "No sabes cuánto tiempo te queda..."
if saxons_follow>10
narrate "Los sajones te capturan. Su general, sonriendo ampliamente, dice:"
speak "Bien, bien... Del gran Ulfius podremos sacar una buena ventaja."
end_of_scene:clear_screen
action_end
endif
ret
endif
if current_location<10 and not location_exit(8,north)
narrate "Tus hombres luchan con denuedo contra los sajones."
ret
endif
if current_location=20 and (not is_it_accessible(the_torch) or not lit_the_torch)
rem por qué >19?!!! Pongo =20, que es la salida desde la 17
narrate "Ante la reinante e intimidante oscuridad, retrocedes a donde puedes ver."
short_pause
let current_location=17
action_look
ret
endif
if current_location=51
narrate "Agotado, das parte en el castillo de tu llegada y de lo que ha pasado."
short_pause
narrate "Pides audiencia al rey, Uther Pendragon."
end_of_scene:clear_screen
speak "El rey"&r_quote$&", te indica el valido, "&l_quote$&"ha ordenado que no se le moleste, pues sufre una amarga tristeza."
short_pause
narrate "No puedes entenderlo. El rey, tu amigo."
short_pause
narrate "Agotado, decepcionado, apesadumbrado, decides ir a dormir a tu casa. Es lo poco que puedes hacer."
short_pause
narrate "Te has ganado un buen descanso."
end_of_scene:clear_screen
action_end
endif
enddef
defproc location_plot
rem Comprueba las condiciones de la trama relacionadas con el nuevo escenario.
rem Check the plot conditions related to the new location.
sel on current_location
=11,38,44
let location(the_lake)=current_location
=1 to 9
if location_exit(8,north):narrate "Tus hombres siguen tus pasos."
=16
narrate "En la distancia, por entre los resquicios de las rocas, y allende el canal de agua, los sajones tratan de buscar la salida que encontraste por casualidad."
=31
if location_exit(31,north)
narrate "Las rocas yacen desmoronadas a lo largo del pasaje."
else
narrate "Las rocas bloquean el camino."
endif
=28
let location_exit(28,east)=false
endsel
if not is_it_vanished(ambrosio) and can_be_taken(the_key) and (current_location=46 or ambrosio_follows)
let location(ambrosio)=current_location
narrate "Tu benefactor te sigue, esperanzado."
endif
enddef
defproc rocks_and_log
rem Acción de usar el tronco con las rocas.
rem Action using the log with rocks.
if hacked_the_log
narrate "Haciendo palanca, consigues desencajar una, y el resto caen por su propio peso."
do_vanish the_rocks
let location_exit(31,north)=32
else
narrate "Lo intentas con el tronco, pero la punta es demasiado gruesa, y no penetra entre los resquicios de las rocas."
endif
enddef
defproc open_the_door
rem Acción de abrir la puerta.
rem Action opening the door.
narrate "La puerta se abre, rechinando, mientras hiedras y hierbas se rompen en su trazado."
short_pause
narrate "Ambrosio, alegre, se despide de ti."
speak "Estoy seguro de que volveremos a vernos"&r_quote$&", dice."
narrate "Se ha ido."
do_vanish ambrosio
do_vanish the_key
let thing_description$(the_door)="Entreabierta."
let thing_description$(the_lock)="Abierto."
let location_exit(47,west)=48
enddef
rem --------------------------------------------
rem Analizador
rem Parser
defproc command
rem Acepta un comando, lo analiza y lo ejecuta.
rem Accept a command, analize it and execute it.
loc next_space,command$
let action=false
let object=false
let complement=false
let command$=accept$
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
if fine_command:do_action action
enddef
defproc parse_word(word$)
rem Analiza la palabra dada.
rem Analize the given word.
if not action
let action=parse_verb(word$)
else
if not object
let object=parse_noun(word$)
else
if not complement:complement=parse_noun(word$)
endif
endif
enddef
deffn parse_verb(word$)
rem Analiza la palabra dada, supuestamente un verbo.
rem Analize the given word; it's supposed to be a verb.
loc found
let found=inarray%(verb$,0,word$)
if found<0:ret 0
ret the_action(found)
enddef
deffn parse_noun(word$)
rem Analiza la palabra dada, supuestamente un sustantivo.
rem Analize the given word; it's supposed to be a noun.
loc found
let found=inarray%(noun$,0,word$)
if found<0:ret 0
ret the_thing(found)
enddef
deffn fine_command
rem Comprueba si el comando es correcto, tanto por las partes que lo componen como por la accesibilidad de objeto y complemento, si existen. Devuelve 1 si es correcto y 0 en caso contrario.
rem Check if the command is right: check its parts and the accesibility of the object and the complement, if present. Return 1 if it's right, or 0 otherwise.
loc syntax
let syntax=action_syntax(action)
if not action:narrate "No conozco ese verbo.":ret 0
sel on syntax
=object_needed:if not object:narrate not_seen$:ret 0
=object_and_complement_needed:if (not object or not complement):narrate not_seen$:ret 0
endsel
if object:if not is_it_accessible(object):narrate not_seen$:ret 0
if complement:if not is_it_accessible(complement):narrate not_seen$:ret 0
ret 1
enddef
rem --------------------------------------------
rem Acciones
rem Actions
defproc do_action(action)
sel on action
=to_break:action_break
=to_drop:action_drop
=to_examine:action_examine
=to_finish:action_end
=to_fling:action_fling
=to_go_down:action_move down
=to_go_east:action_move east
=to_go_north:action_move north
=to_go_south:action_move south
=to_go_up:action_move up
=to_go_west:action_move west
=to_help:action_help
=to_insert:action_insert
=to_look:action_look
=to_open:action_open
=to_speak:action_speak
=to_swim:action_swim
=to_take:action_take
=remainder:narrate "No puedes hacer eso."
endsel
enddef
defproc action_help
narrate "Direcciones: n[orte], s[ur], e[ste], o[este], a[rriba] y [a]b[ajo]."
narrate "m[irar] redescribe un lugar, ex[aminar] permite examinar un objeto, o en su defecto a ti."
narrate "Se puede cortar, nadar, atacar, empujar, golpear, coger, dejar, tirar..."
narrate "Se aceptan formas verbales en infinitivo e imperativo; y diversos sinónimos tanto de verbos como de nombres."
narrate "El atajo de teclado Ctrl+B (des)activa el bip de error de tecleo."
enddef
defproc action_examine
if object
if is_it_accessible(object)
narrate thing_description$(object)
else
narrate not_seen$
endif
else
action_inventory
endif
enddef
defproc action_end
if yes("¿Quieres volver a intentarlo?")
let start_over=true
else
clear_screen:stop
endif
enddef
defproc action_swim
if current_location=11
clear_screen
narrate "Caes hacia el fondo por el peso de tu coraza. Como puedes, te desprendes de ella y buceas, pensando en avanzar, aunque perdido."
short_pause
narrate "Consigues emerger, si bien en un sitio desconocido de la caverna..."
end_of_scene
let current_location=12
action_look
else
narrate "No tiene sentido nadar ahora."
endif
enddef
defproc action_open
if current_location=47
if object=the_door or object=the_lock
if is_it_accessible(the_key)
open_the_door
else
narrate "El candado bloquea la puerta."
endif
else
narrate "No tiene sentido abrir eso."
endif
else
narrate "No hay nada que abrir ahora."
endif
enddef
defproc action_drop
sel on object
=the_sword:if current_location<12:narrate "No, es lo que queda de mi padre.":ret
=the_torch:if lit_the_torch:narrate "No, sin luz es imposible moverse por la caverna.":ret
endsel
if location(object)=ulfius
let location(object)=current_location
narrate "Hecho."
else
narrate i_dont_have_it$
endif
enddef
defproc action_take
if location(object)=ulfius
narrate "Pero si ya lo tengo..."
else
if cannot_be_taken(object)
if object=the_key
narrate "Ambrosio la retiene consigo."
else
narrate "No es algo que se pueda coger."
endif
else
let location(object)=ulfius:narrate "Hecho."
endif
endif
enddef
defproc action_break
if not complement and is_it_accessible(the_sword)
let complement=the_sword
endif
sel on object
=the_log
if hacked_the_log
narrate "La punta ya es lo suficientemente afilada."
else
sel on complement
=false:narrate not_by_hand$
=the_sword
narrate "Sabes que el resultado es la hoja de tu espada, mellada. No."
=the_flint
let hacked_the_log=true
let thing_description$(the_log)=thing_description$(the_log)&" Su punta está afilada."
narrate "Con el pedernal, recortas la punta del tronco."
=remainder
narrate "El problema es encontrar la herramienta adecuada para hacerlo."
endsel
endif
=the_cloak
sel on complement
=false:narrate not_by_hand$
=the_sword
do_vanish the_cloak
let location(the_rags)=ulfius
let location(the_thread)=ulfius
let location(the_piece)=ulfius
narrate "Rasgas la capa, como buenamente puedes."
=remainder
narrate not_with_that$
endsel
=the_rocks
sel on complement
=false:narrate not_by_hand$
=the_log:rocks_and_log
=the_sword:narrate "Tu espada no hace nada."
=remainder:narrate not_with_that$
endsel
=the_flint
sel on complement
=false:narrate not_by_hand$
=the_sword
if is_it_accessible(the_torch)
let lit_the_torch=true
let thing_description$(the_torch)="Ilumina perfectamente."
narrate "Poderosas chispas salen del choque entre espada y pedernal, encendiendo la antorcha."
else
narrate "Ante el potente choque con la espada, poderosas chispas saltan en todas direcciones."
endif
=remainder:narrate not_with_that$
endsel
=the_snake
sel on complement
=false:narrate not_by_hand$
=the_sword
narrate "Ante los amenazadores tajos, la serpiente huye."
do_vanish the_snake
let location_exit(43,south)=44
=remainder:narrate not_with_that$
endsel
=remainder:narrate "Eso no es lo adecuado ahora."
endsel
enddef
defproc action_speak
sel on object
=ambrosio:talk_to_ambrosio
=the_man:talk_to_the_man
=remainder:narrate "No tiene sentido hablar con eso."
endsel
enddef
defproc talk_to_ambrosio
if location(ambrosio)=19
speak "Hola, buen hombre."
speak "Hola, Ulfius. Mi nombre es Ambrosio."
end_of_scene:clear_screen
narrate "Por primera vez, Ulfius se sienta y cuenta a Ambrosio todo lo que ha pasado. Y tras tanto acontecido, llora desconsoladamente."
end_of_scene:clear_screen
narrate "Ambrosio le propone un trato, que acepta: por ayudarle a salir de la cueva, objetos, vitales para la empresa, le son entregados."
let location(the_torch)=ulfius
let location(the_flint)=ulfius
short_pause
speak "Bien, Ambrosio, emprendamos la marcha."
let location(ambrosio)=46
narrate "Ulfius se da la vuelta para ver si Ambrosio le sigue, pero... ha desaparecido."
short_pause
narrate "Ulfius piensa entonces en el hecho curioso de que supiera su nombre."
end_of_scene:clear_screen
else
if current_location=46
if not ambrosio_follows
speak "La llave, Ambrosio, estaba ya en tu poder. Y es obvio que conocéis un camino más corto."
speak "Estoy atrapado en la cueva debido a magia de maligno poder. En cuanto al camino, vos debéis hacer el vuestro, verlo todo con vuestros ojos."
narrate "Ulfius sacude la cabeza."
speak "No lo entiendo, la verdad."
endif
endif
if current_location>=45 and current_location<=47
speak "Por favor, Ulfius, cumple tu promesa. Toma la llave en tu mano y abre la puerta de la cueva."
let location(the_key)=ulfius
do_takeable the_key
let ambrosio_follows=true
endif
endif
enddef
defproc talk_to_the_man
if not talked_to_the_man
speak "Me llamo Ulfius y..."
let talked_to_the_man=true
narrate "El hombre asiente, impaciente."
speak "Somos refugiados de la gran guerra. Buscamos la paz."
short_pause
endif
if is_it_accessible(the_stone)
narrate "El hombre se irrita."
speak "No podemos permitiros huir con la piedra del druida."
narrate "Hace un gesto..."
short_pause
speak "La piedra debe devolverse a su lugar de encierro."
narrate "Un hombre te arrebata la piedra y se la lleva."
let location(the_stone)=18
else
if is_it_accessible(the_sword)
narrate "El hombre se enfurece, y alza su mano indicando al norte."
speak "Nadie portando armas puede pasar."
else
let location_exit(28,east)=29
narrate "El hombre, calmado, indica hacia el este y habla:"
speak "Si vienes en paz, puedes ir en paz."
narrate "Todos se apartan y permiten ahora el paso al este."
endif
endif
enddef
defproc action_fling
sel on current_location
=13,16
narrate "No hay suficiente profundidad."
=19
if (object=the_sword or object=the_stone) and talked_to_the_man
let location(object)=39
narrate "La corriente lo arrastra fuertemente, hasta perderlo de vista."
else
narrate "No quieres perder eso."
endif
=remainder:
narrate "No tiene sentido tirar nada ahora."
endsel
enddef
defproc action_insert
sel on complement
=the_rocks
if object=the_log
rocks_and_log
else
narrate "No tiene sentido meter eso ahí."
endif
=the_idol
sel on object
=the_emerald,the_stone
do_vanish object
narrate "Encaja. Metido. Desaparece en su interior."
if is_it_vanished(the_stone) and is_it_vanished(the_emerald)
let location_exit(41,south)=42
narrate "La gran roca se desplaza y deja el paso libre."
endif
=remainder
narrate "No encaja."
endsel
=the_lock
if object=the_key
narrate "La llave gira fácilmente dentro del candado."
short_pause
open_the_door
else
narrate "No tiene sentido meter eso ahí."
endif
=remainder
narrate "No tiene sentido meter nada en eso."
endsel
enddef
defproc action_move(direction)
if location_exit(current_location,direction)
let current_location=location_exit(current_location,direction)
action_look
else
narrate "No es posible."
endif
enddef
defproc action_inventory
loc i,list$
let list$=""
for i=1 to things
if location(i)=ulfius:let list$=list$&" - "&thing$(i)&nl$
endfor i
if len(list$)
narrate "Llevo conmigo:"&nl$&list$
else
narrate "No llevo nada conmigo."
endif
enddef
defproc action_look
clear_screen
rem narrate "["¤t_location&"]":rem debug!!!
describe location_description$(current_location)
location_plot
list_present_things
enddef
defproc list_present_things
loc n,list$
let list$=""
for n=1 to things
if location(n)=current_location
if is_it_a_person(n)
let list$=list$&" - "&iso_upper_1$(thing$(n))&nl$
else
let list$=list$&" - "&thing$(n)&nl$
endif
endif
endfor n
if len(list$)
narrate "Puedes ver:"&nl$&list$
endif
enddef
rem --------------------------------------------
rem Intefaz de datos
rem Data interface
deffn is_it_a_person(thing)
ret thing_type(thing)=2
enddef
defproc do_takeable(thing)
let thing_type(thing)=false
enddef
defproc do_not_takeable(thing)
let thing_type(thing)=true
enddef
deffn can_be_taken(thing)
ret not thing_type(thing)
enddef
deffn cannot_be_taken(thing)
ret thing_type(thing)
enddef
deffn is_it_here(thing)
ret location(thing)=current_location
enddef
deffn is_it_hold(thing)
ret location(thing)=ulfius
enddef
deffn is_it_accessible(thing)
ret is_it_hold(thing) or is_it_here(thing)
enddef
defproc do_vanish(thing)
let location(thing)=limbo
enddef
deffn is_it_vanished(thing)
ret location(thing)=limbo
enddef
rem --------------------------------------------
rem Entrada
rem Input
deffn accept$
rem Devuelve un nuevo comando del usuario, preparado para su análisis.
rem Return a new user command, formatted for the parsing.
loc command$
ink #tw,yellow
print #tw,"> ";
let command$=iso_input$(#tw,0)
if command$(len(command$))<>" ":let command$=command$&" "
ink #tw,light_grey
ret command$
enddef
deffn iso_input$(channel,max_chars)
rem Devuelve un texto tecleado por el usuario.
rem Return a text typed by the user.
rem channel =
rem Canal de la ventana a utilizar, en la posición actual del cursor.
rem Channel of the window to be used, at the current cursor position.
rem max_chars =
rem Longitud máxima; si es cero, será la máxima posible en la línea actual con el tamaño actual de letra.
rem Maximum length. If it's zero, it will be the maximum possible on the current line, with the current character size.
rem Los caracteres castellanos son convertidos al estándar ISO 8859-1; todas las letras son convertidas a minúsculas;
rem No permite: espacios iniciales o dobles, dígitos y signos de puntuación.
rem Spanish chars are translated to ISO 8859-1; all letters are made lowercase.
rem Not allowed: starting or double spaces, digits and punctuation.
loc output$,key$,key,cursor_pos,cursor_x0,cursor_y0
let output$=""
let cursor_pos=1
let cursor_x0=pos_x(#channel)
let cursor_y0=pos_y(#channel)
if max_chars=0
let max_chars=char_x(#channel)-cursor_x0/char_w(#channel)-2
endif
cursen #channel
rep typing
let key$=inkey$(#channel,-1)
let key=code(key$)
sel on key
=2:let mistype_bell_active=not mistype_bell_active:rem Ctrl+B
=9:tab 8:rem Tab
=enter:if len(output$):exit typing:else mistype_bell
=space:type_space
=65 to 90:type chr$(key+32)
=97 to 122:type key$
=131,163:type chr$(233):rem é/É
=135,167:type chr$(252):rem ü/Ü
=137,169:type chr$(241):rem ñ/Ñ
=140:type chr$(225):rem á
=147:type chr$(237):rem í
=150:type chr$(243):rem ó
=153:type chr$(250):rem ú
=192:cursor_left
=193:start_of_line:rem Alt+Left
=194:backspace_char:rem Ctrl+Left
=195:delete_line_left:rem Ctrl+Alt+Left
=196:previous_word:rem Shift+Left
=200:cursor_right
=201:end_of_line:rem Alt+Right
=202:delete_char:rem Ctrl+Right
=203:delete_line_right:rem Ctrl+Alt+Right
=204:next_word:rem Shift+Right
=253:tab -8:rem Shift+Tab
endsel
endrep typing
curdis #channel
print #channel\\\
ret output$
enddef
defproc type(char$)
rem Si hay espacio, añade al texto el caracter indicado y lo imprime.
rem If there is space, add the given character and type it.
if len(output$)<max_chars
sel on cursor_pos
=len(output$)+1
let output$=output$&char$
=remainder
let output$=output$(1 to cursor_pos-1)&char$&output$(cursor_pos to)
endsel
let cursor_pos=cursor_pos+1
show_input
else
mistype_bell
endif
enddef
defproc type_space
rem Si es posible, añade al texto un espacio y lo imprime.
rem If possible, add a space and type it.
if cursor_pos=1
mistype_bell
else
if cursor_pos>len(output$)
if output$(cursor_pos-1)=" "
mistype_bell
else
type " "
endif
else
if output$(cursor_pos)=" " or output$(cursor_pos-1)=" "
mistype_bell
else
type " "
endif
endif
endif
enddef
defproc tab(offset)
rem Si es posible, suma a la posición del cursor el desplazamiento indicado.
rem If possible, add the given offset to the cursor position.
if (offset<1 and cursor_pos=1) or (offset>0 and cursor_pos=len(output$)+1)
mistype_bell
else
let cursor_pos=cursor_pos+offset
let cursor_pos=maximum(cursor_pos,1)
let cursor_pos=minimum(cursor_pos,len(output$)+1)
set_cursor cursor_pos
endif
enddef
defproc start_of_line
rem Sitúa el cursor al inicio de la línea.
rem Put the cursor at the start of the line.
let cursor_pos=1
set_cursor cursor_pos
enddef
defproc end_of_line
rem Sitúa el cursor al final de la línea.
rem Put the cursor at the end of the line.
let cursor_pos=len(output$)+1
set_cursor cursor_pos
enddef
defproc backspace_char
rem Si es posible, borra el carácter a la izquierda del cursor
rem If possible, delete the character at the left of the cursor.
loc original$
if len(output$)
if cursor_pos=1
mistype_bell
else
let original$=output$
let output$=original$(1 to cursor_pos-2)
if cursor_pos<=len(original$)
let output$=output$&original$(cursor_pos to)
endif
let cursor_pos=cursor_pos-1
show_input
endif
else
mistype_bell
endif
enddef
defproc delete_char
rem Si es posible, borra el carácter bajo el cursor.
rem If possible, delete the character under the cursor.
loc original$
if len(output$)
if cursor_pos=len(output$)+1
mistype_bell
else
let original$=output$
let output$=original$(1 to cursor_pos-1)
if cursor_pos<len(original$)
let output$=output$&original$(cursor_pos+1 to)
endif
show_input
endif
else
mistype_bell
endif
enddef
defproc delete_line_right
rem Si es posible, borra hasta el final de la línea.
rem If possible, delete to end of line.
if len(output$)
if cursor_pos=len(output$)+1
mistype_bell
else
let output$=output$(1 to cursor_pos-1)
show_input
endif
else
mistype_bell
endif
enddef
defproc delete_line_left
rem Si es posible, borra toda la línea a la izquierda del cursor
rem If possible, delete the character at the left of the cursor.
if len(output$)
if cursor_pos=1
mistype_bell
else
let output$=output$(cursor_pos to)
let cursor_pos=1
show_input
endif
else
mistype_bell
endif
enddef
defproc cursor_left
rem Si es posible, desplaza el cursor un carácter a la izquierda.
rem If possible, move the cursor one character left.
if cursor_pos>1
curdis #channel
let cursor_pos=cursor_pos-1
set_cursor cursor_pos
cursen #channel
else
mistype_bell
endif
enddef
defproc cursor_right
rem Si es posible, desplaza el cursor un carácter a la derecha.
rem If possible, move the cursor one character right.
if cursor_pos<len(output$)+1
curdis #channel
let cursor_pos=cursor_pos+1
set_cursor cursor_pos
cursen #channel
else
mistype_bell
endif
enddef
defproc previous_word
rem Si es posible, desplaza el cursor al inicio de la palabra anterior.
rem If possible, move the cursor to the start of the previous word.
loc temp,from_char,to_char
if cursor_pos=1
mistype_bell
else
let temp=0
let to_char=code(output$(cursor_pos-(cursor_pos>len(output$))))
let from_char=to_char
rep search
if not ((cursor_pos>1) and not(from_char<>space and to_char=space and temp>1)):exit search
let from_char=to_char
let cursor_pos=cursor_pos-1
let temp=temp+1
let to_char=code(output$(cursor_pos))
endrep search
let cursor_pos=cursor_pos+(cursor_pos<>1)
set_cursor cursor_pos
show_input
endif
enddef
defproc next_word
rem Si es posible, desplaza el cursor al inicio de la palabra siguiente (o al final de la última palabra).
rem If possible, move the cursor to the start of the next word (or to the end of the last word).
loc from_char,to_char
if cursor_pos>len(output$)
mistype_bell
else
let to_char=code(output$(cursor_pos))
let from_char=to_char
rep search
if not ((cursor_pos<len(output$)) and not(from_char=space and to_char<>space)):exit search
let from_char=to_char
let cursor_pos=cursor_pos+1
let to_char=code(output$(cursor_pos))
endrep search
let cursor_pos=cursor_pos+(cursor_pos=len(output$))
set_cursor cursor_pos
show_input
endif
enddef
defproc show_input
rem Muestra el texto actual.
rem Show the current text.
curdis #channel
set_cursor 1
print #channel,output$;
cls #channel,4
set_cursor cursor_pos
cursen #channel
enddef
defproc set_cursor(column)
rem Sitúa el cursor de texto en la posición de pixeles correspondiente a la columna indicada (que es relativa al texto que se está escribiendo).
rem Set the text cursor at the pixel position of the given column (which is relative to the typed text).
cursor #channel,cursor_x0+(column-1)*char_w(#channel),cursor_y0
enddef
defproc mistype_bell
rem Sonido de error de tecleo.
rem Mistype sound.
if mistype_bell_active:beep 1000,0
enddef
deffn yes(question$)
rem Muestra la pregunta indicada y espera la pulsación de las teclas S o N (sin distinguir minúsculas de mayúsculas). Devuelve 1 si se pulsó S; 0 si se pulsó N.
rem Show the given question and wait for S or N to be pressed (ignoring case). Return 1 if S was pressed; 0 otherwise.
loc answer$
cursen #tw
print #tw,question$!"(S/N)"!;
rep answer
let answer$=inkey$(#tw,-1)
if answer$ instr "sn"
exit answer
else
mistype_bell
endif
endrep answer
curdis #tw
ret answer$ instr "s"
enddef
defproc end_of_scene
rem Muestra un presto y hace una pausa larga.
rem Show a prompt and do a long pause.
ink #tw,dark_green
print #tw,"..."\\
long_pause
enddef
defproc short_pause
rem Hace una pausa corta; se usa entre ciertos párrafos.
rem Do a short pause; it's used between certain paragraphs.
wait_for_key_press(2)
enddef
defproc long_pause
rem Hace una pausa larga; se usa tras cada escena.
rem Do a long pause; it's used after every scene.
wait_for_key_press(16)
enddef
defproc wait_for_key_press(seconds)
rem Espera los segundos indicados, o hasta que se pulse una tecla.
rem Wait the given seconds, or until a key is pressed.
loc start_time
let start_time=date
rep dont_press_a_key
if inkey$(#tw)="" or date>start_time+seconds
exit dont_press_a_key
endif
endrep dont_press_a_key
rep press_a_key
if inkey$(#tw)<>"" or date>start_time+seconds
exit press_a_key
endif
endrep press_a_key
enddef
rem --------------------------------------------
rem Cadenas
rem Strings
deffn iso_upper(char)
rem Devuelve el código de mayúscula correspondiente al carácter ISO 8859-1 indicado.
rem Return the uppercase char code of the given ISO 8859-1 char.
loc c:let c=char:rem QDOS y Minerva necesitan esto / QDOS and Minerva need this
sel on c
=97 to 122,224 to 246,248 to 254:ret c-32
=remainder:ret c
endsel
enddef
deffn iso_upper$(text$)
rem Devuelve en mayúsculas un texto ISO 8859-1.
rem Return the given ISO 8859-1 text in uppercase.
loc i,upper_text$
let upper_text$=text$
for i=1 to len(upper_text$)
let upper_text$(i)=chr$(iso_upper(code(text$(i))))
endfor i
ret upper_text$
enddef
deffn iso_upper_1$(text$)
rem Devuelve el texto ISO 8859-1 dado, con la primera letra en mayúlculas.
rem Return the given ISO 8859-1 text with the first letter in uppercase.
ret iso_upper$(text$(1))&text$(2 to)
enddef
rem --------------------------------------------
rem Pantalla
rem Screen
defproc clear_screen
ink #tw,light_grey
cls #tw
enddef
rem --------------------------------------------
rem Salida de textos
rem Text output
defproc speak(quote$)
rem Imprime una cita de un diálogo, con las comillas adecuadas.
rem Print a dialog quote, with the proper quote chars.
loc last
ink #tw,yellow
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
enddef
defproc describe(txt$)
rem Imprime la descripción de un escenario.
rem Print a location description.
ink #tw,dark_cyan:tell txt$
enddef
defproc narrate(txt$)
rem Imprime texto de la narración.
rem Print a narrative text.
ink #tw,light_grey:tell txt$
enddef
defproc tell(txt$)
rem Imprime un texto justificado a la izquierda.
rem Print a text, left justified.
loc text$,first,last
if len(txt$)
let text$=txt$&" "
let first=1
for last=1 to len(text$)
if text$(last)=" "
print #tw,!text$(first to last-1);
let first=last+1
endif
endfor last
endif
print #tw,\\
enddef
rem --------------------------------------------
rem Acerca de
rem About
defproc about
rem Muestra los créditos.
rem Show the credits.
clear_screen
ink #tw,light_red:print #tw,"Asalto y castigo"
ink #tw,dark_cyan
print #tw,\"Por Baltasar el Arquero, 2009"
print #tw,"http://caad.es/baltasarq/"
print #tw,\"Reescrita en SuperBASIC para QL por"
print #tw,"Marcos Cruz (programandala.net), 2011"
print #tw,"http://programandala.net/"
print #tw,"Versión"!version$
ink #tw,light_grey
print #tw,\\"http://www.caad.es/"
print #tw,"http://www.sinclairql.es/"\\\
enddef
defproc intro
rem Introducción al juego.
rem Game intro.
clear_screen
narrate "El sol despunta de entre la niebla, haciendo humear los tejados de paja."
short_pause
narrate "Piensas en el encargo realizado por Uther Pendragon. Atacar una aldea tranquila, aunque sea una llena de sajones, no te llena de orgullo."
short_pause
narrate "Los hombres se ciernen sobre la aldea, y la destruyen. No hubo tropas enemigas, ni honor en la batalla."
end_of_scene:clear_screen
speak "Sire Ulfius, la batalla ha terminado."
narrate "Lentamente, das la orden de volver a casa. Los oficiales detienen como pueden el saqueo."
end_of_scene:clear_screen
enddef
rem --------------------------------------------
rem Inicialización
rem Init
defproc first_time_init
rem Inicialización necesaria solo una vez.
rem Init needed only once.
init_the_constants
init_the_preferences
clear_screen
enddef
defproc game_init
rem Inicialización necesaria antes de cada partida.
rem Init needed before every game.
loc y
let y=pos_y(#tw)
print #tw,"Preparando los datos..."
init_the_flags
init_the_data
let current_location=1
cls #tw,3
cursor #tw,0,y
enddef
defproc init_the_preferences
rem Inicializa las preferencias de juego.
rem Init the game preferences.
let mistype_bell_active=true
enddef
defproc init_the_constants
rem Inicializa todas las constantes.
rem Init all the constants.
rem Varios
rem Misc
let space=32:rem char code
let enter=10:rem char code
let nl$=chr$(enter):rem new line
let l_quote$="«":rem castilian left quote
let r_quote$="»":rem castilian right quote
let limbo=255:rem location of vanished things
rem Action syntax flags
rem Indicadores de sintaxis de las acciones
let no_object_needed=0
let object_needed=1
let object_and_complement_needed=2
rem Mensajes de error
rem Error messages
let not_seen$="No lo veo, o no es importante."
let i_dont_have_it$="No llevo eso conmigo."
let not_with_that$="Con eso no..."
let not_by_hand$="En cualquier caso, no con las manos desnudas."
rem Identificadores de acciones
rem Action ids
let to_go_down=1
let to_open=2
let to_go_up=3
let to_break=4
let to_help=5
let to_swim=6
let to_take=7
let to_drop=8
let to_go_east=9
let to_examine=10
let to_speak=11
let to_insert=12
let to_look=13
let to_go_north=14
let to_go_west=15
let to_go_south=16
let to_finish=17
let to_fling=18
rem Identificadores de cosas
rem Thing ids
let ulfius=0
let the_altar=1
let ambrosio=2
let the_torch=3
let the_flags=4
let the_cloak=5
let the_waterfall=6
let the_fallen_away=7
let the_emerald=8
let the_sword=9
let the_rags=10
let the_thread=11
let the_man=12
let the_idol=13
let the_lake=14
let the_key=15
let the_flint=16
let the_stone=17
let the_door=18
let the_rocks=19
let the_snake=20
let the_log=21
let the_piece=22
let the_lock=23
rem Identificadores de direcciones
rem Direction ids
let north=0
let south=1
let east=2
let west=3
let up=4
let down=5
let first_direction=north
let last_direction=down
enddef
defproc init_the_flags
rem Inicializa los indicadores del juego.
rem Init the game flags.
let ambrosio_follows=false:rem ¿Ambrosio nos sigue? / Does Ambrosio follow me?
let saxons_follow=false:rem ¿Los sajones nos siguen? / Do the saxons follow me?
let talked_to_the_man=false:rem ¿Hemos hablado con el hombre? / Have I talked to the man?
let hacked_the_log=false:rem ¿Hemos afilado el tronco? / Did I hacked the log?
let lit_the_torch=false:rem ¿Está la antorcha encendida? / Is the torch lit?
let start_over=false:rem ¿Empezar una nueva partida? / Do I start a new game?
enddef
defproc init_the_data
rem Inicializa las matrices de datos. El primer elemento (0) de las matrices no se usa, salvo para las direcciones.
rem Init the data arrays. The first element (0) of the arrays is not used, except for the directions.
loc i,j,max_word_lenght,action
let max_word_lenght=11
restore
let locations=lines_between("label_location_descriptions_start","label_location_descriptions_end")
dim location_description$(locations,255)
for i=1 to locations
read location_description$(i)
endfor i
dim location_exit(locations,last_direction)
for i=1 to locations
for j=first_direction to last_direction
read location_exit(i,j)
endfor j
endfor i
let nouns=lines_between("label_nouns_start","label_nouns_end")
dim noun$(nouns,max_word_lenght)
dim the_thing(nouns)
let things=lines_between("label_things_start","label_things_end")/2
dim thing$(things,max_word_lenght)
rem Nota: El último sinónimo listado será el nombre principal de cada cosa.
rem Note: The last synonym on the list will be the actual thing name.
for i=1 to nouns
read the_thing(i),noun$(i)
let thing$(the_thing(i))=noun$(i)
endfor i
dim location(things)
dim thing_type(things)
dim thing_description$(things,128)
for i=1 to things
read thing
read location(thing),thing_type(thing)
read thing_description$(thing)
endfor i
let actions=lines_between("label_actions_start","label_actions_end")
dim action_syntax(actions)
for i=1 to actions
read action
read action_syntax(action)
endfor i
let verbs=lines_between("label_verbs_start","label_verbs_end")
dim verb$(verbs,max_word_lenght)
dim the_action(verbs)
let action=1
let last_action=0
for i=1 to verbs
read the_action(i),verb$(i)
endfor i
enddef
rem --------------------------------------------
rem Datos
rem Data
rem Descripciones de los escenarios
rem Location descriptions
defproc label_location_descriptions_start:enddef
data "Aldea Sajona. No ha quedado nada en pie, ni piedra sobre piedra. El entorno es desolador. Solo resta volver al sur, a casa."
data "Sobre la colina, casi sobre la niebla de la aldea sajona arrasada al norte, a tus pies. El camino desciende hacia el oeste."
data "Camino entre colinas. El camino avanza por el valle, desde la parte alta, al este, a una zona harto boscosa, al oeste."
data "Cruce de caminos. Una senda parte al oeste, a la sierra por el paso del Perro, y otra hacia el norte, por un frondoso bosque que la rodea."
data "Desde la linde, al sur, hacia el oeste se extiende frondoso el bosque que rodea la sierra. La salida se abre hacia el sur."
data "Bosque. Jirones de niebla se enzarcen en frondosas ramas y arbustos. La senda serpentea entre raíces, de un luminoso este al oeste."
data "Paso del Perro. Abruptamente, del bosque se pasa a un estrecho camino entre altas rocas. El inquietante desfiladero tuerce de este a sur."
data "Entrada a la cueva. El paso entre el desfiladero sigue de norte a este. La entrada a una cueva se abre al sur en la pared de roca."
data "Derrumbe. El camino desciende hacia la agreste sierra, al oeste, desde los verdes valles al este. Pero un gran derrumbe bloquea la sierra."
data "Gruta de entrada. El estrecho paso se adentra hacia el oeste, desde la boca, al norte. "
data "Gran lago. Una gran estancia alberga un lago de profundas e iridiscentes aguas, debido a la luz exterior. No hay otra salida que el este."
data "Salida del paso secreto. Una gran estancia se abre hacia el oeste, y se estrecha hasta morir, al este, en una parte de agua."
data "Puente semipodrido. La sala se abre en semioscuridad a un puente cubierto de podredumbre sobre el lecho de un canal, de este a oeste."
data "Recodo de la cueva. La iridiscente cueva gira de este a sur."
data "Pasaje arenoso. La gruta desciende de norte a sur sobre un lecho arenoso. Al este, un agujero del que llega claridad."
data "Pasaje del agua. Como un acueducto, el agua baja con gran fuerza de norte a este, aunque la salida practicable es la del oeste."
data "Estalactitas. Muchas estalactitas se agrupan encima de tu cabeza, y se abren cual arco de entrada hacia el este y sur."
data "Puente de piedra. Un arco de piedra se eleva, cual puente sobre la oscuridad, de este a oeste. En su mitad, un altar."
data "Recodo arenoso del canal. La furiosa corriente, de norte a este, impide el paso, excepto al oeste. Al fondo, se oye un gran estruendo."
data "Un tramo de cueva estrecho te permite avanzar hacia el norte y el sur; un pasaje surge al este."
data "Un tramo de cueva estrecho te permite avanzar de este a oeste; un pasaje surge al sur."
data "Un tramo de cueva estrecho te permite avanzar de este a oeste; un pasaje surge al sur."
data "Un tramo de cueva estrecho te permite avanzar de oeste a sur."
data "Un tramo de cueva estrecho te permite avanzar de este a norte."
data "Un tramo de cueva estrecho te permite avanzar de este a oeste. Al norte y al sur surgen pasajes."
data "Un tramo de cueva estrecho te permite avanzar de este a oeste. Al norte surge un pasaje."
data "Un tramo de cueva estrecho te permite avanzar al oeste. Al norte surge un pasaje."
data "Refugio. Una amplia estancia de norte a este, hace de albergue a refugiados: hay banderas de ambos bandos. Un hombre anciano te contempla. Los refugiados te rodean."
data "Espiral. Cual escalera de caracol gigante, desciende a las profundidades, dejando a los refugiados al oeste."
data "Inicio de la espiral. Se eleva en la penumbra. La caverna se estrecha ahora como para una sola persona, hacia el este."
data "Puerta norte. En este pasaje grandes rocas se encuentran entre las columnas de un arco de medio punto."
data "Precipicio. El camino ahora no excede de dos palmos de cornisa sobre un abismo insondable. El soporte de roca gira en 'U' de oeste a sur."
data "Pasaje de salida. El paso se va haciendo menos estrecho a medida que se avanza hacia el sur, para entonces comenzar hacia el este."
data "Pasaje de gravilla. El paso se anchea de oeste a norte, y guijarros mojados y mohosos tachonan el suelo de roca."
data "Puente sobre el acueducto. Un puente se tiende de norte a sur sobre el curso del agua. Resbaladizas escaleras descienden hacia el oeste."
data "Remanso. Estruendosa corriente baja con el pasaje elevado desde el oeste, y forma un meandro arenoso. Unas escaleras suben al este."
data "Canal de agua. El agua baja del oeste con renovadas fuerzas, dejando un estrecho paso elevado lateral para avanzar a este o a oeste."
data "Gran cascada. Cae el agua hacia el este, descendiendo con gran fuerza hacia el canal, no sin antes embalsarse en un lago poco profundo."
data "Interior de la cascada. Musgoso y rocoso, con la cortina de agua tras de ti, el nivel del agua ha crecido un poco en este curioso hueco."
data "Explanada. Una gran explanada enlosetada contempla un bello panorama de estalactitas. Unos casi imperceptibles escalones conducen al este."
data "Ídolo. El ídolo parece un centinela siniestro de una gran roca que se encuentra al sur. Se puede volver a la explanada al oeste."
data "Pasaje estrecho. Como un pasillo que corteja el canal de agua, a su lado, baja de norte a sur. Se aprecia un aumento de luz hacia el sur."
data "Pasaje de la serpiente. El pasaje sigue de norte a sur."
data "Lago interior. Unas escaleras dan paso a un hermoso lago interior, y siguen hacia el oeste. Al norte, un oscuro y estrecho pasaje sube."
data "Cruce de pasajes. Estrechos pasos permiten ir al oeste, al este (menos oscuro), y al sur, un lugar de gran luminosidad."
data "Hogar de Ambrosio. Un catre, algunas velas y una mesa es todo lo que tiene Ambrosio."
data "Salida de la cueva. Por el oeste, una puerta impide, cuando cerrada, la salida de la cueva. Se adivina la luz diurna al otro lado."
data "Bosque a la entrada. Apenas se puede reconocer la entrada de la cueva, al este. El sendero sale del bosque hacia el oeste."
data "Sendero del bosque. El sendero recorre esta parte del bosque de este a oeste."
data "Camino norte. El camino norte de Westmorland se interna hacia el bosque, al norte (en tu estado no puedes ir), y a Westmorland, al sur."
data "Westmorland. La villa bulle de actividad con el mercado en el centro de la plaza, donde se encuentra el castillo."
defproc label_location_descriptions_end:enddef
rem Salidas de los escenarios
rem Location exits
rem datos: n,s,e,o,ar,ab
rem data: n,s,e,w,d,u
data 0,2,0,0,0,0
data 1,0,0,3,0,0
data 0,0,2,4,0,0
data 5,0,3,9,0,0
data 0,4,0,6,0,0
data 0,0,5,7,0,0
data 0,8,6,0,0,0
data 7,10,0,0,0,0
data 0,0,4,0,0,0
data 8,0,0,11,0,0
data 0,0,10,0,0,0
data 0,0,0,13,0,0
data 0,0,12,14,0,0
data 0,15,13,0,0,0
data 14,17,16,0,0,0
data 0,0,0,15,0,0
data 15,20,18,0,0,0
data 0,0,19,17,0,0
data 0,0,0,18,0,0
data 17,22,25,0,0,0
data 0,27,23,20,0,0
data 0,24,27,22,0,0
data 0,25,0,21,0,0
data 22,0,26,0,0,0
data 22,28,23,21,0,0
data 26,0,20,27,0,0
data 27,0,0,25,0,0
data 26,0,0,0,0,0
data 0,0,0,28,0,30
data 0,0,31,0,29,0
data 0,0,0,30,0,0
data 0,33,0,31,0,0
data 32,0,34,0,0,0
data 35,0,0,33,0,0
data 40,34,0,36,0,36
data 0,0,35,37,35,0
data 0,0,36,38,0,0
data 0,0,37,39,0,0
data 0,0,38,0,0,0
data 0,35,41,0,0,0
data 0,0,0,40,0,0
data 41,43,0,0,0,0
data 42,0,0,0,0,0
data 43,0,0,45,0,0
data 0,47,44,46,0,0
data 0,0,45,0,0,0
data 45,0,0,0,0,0
data 0,0,47,49,0,0
data 0,0,48,50,0,0
data 0,51,49,0,0,0
data 50,0,0,0,0,0
rem Nombres
rem Nouns
rem datos: identificador de cosa, nombre
rem (para cada identificador de cosa, el último nombre listado será el principal)
rem data: thing id, noun
rem (for every thing id, the last noun listed will be the main one)
defproc label_nouns_start:enddef
data ambrosio,"ambrosio"
data the_altar,"altar"
data the_cloak,"capa"
data the_door,"puerta"
data the_emerald,"joya"
data the_emerald,"esmeralda"
data the_fallen_away,"derrumbe"
data the_flags,"enseñas"
data the_flags,"pendones"
data the_flags,"banderas"
data the_flint,"pedernal"
data the_idol,"agujero"
data the_idol,"ojo"
data the_idol,"ídolo"
data the_key,"llave"
data the_lake,"agua"
data the_lake,"laguna"
data the_lake,"lago"
data the_lock,"cerrojo"
data the_lock,"cierre"
data the_lock,"candado"
data the_log,"leño"
data the_log,"madero"
data the_log,"tronco"
data the_man,"anciano"
data the_man,"jefe"
data the_man,"viejo"
data the_man,"hombre"
data the_piece,"pedazo"
data the_piece,"trozo"
data the_rags,"harapo"
data the_rocks,"rocas"
data the_snake,"culebra"
data the_snake,"ofidio"
data the_snake,"reptil"
data the_snake,"serpiente"
data the_stone,"piedra"
data the_stone,"pedrusco"
data the_sword,"arma"
data the_sword,"tizona"
data the_sword,"espada"
data the_thread,"hebra"
data the_thread,"hilo"
data the_torch,"antorcha"
data the_waterfall,"catarata"
data the_waterfall,"cascada"
defproc label_nouns_end:enddef
rem Cosas
rem Things
rem datos: identificador,escenario,tipo,descripción
rem data: id,location,type,description
defproc label_things_start:enddef
data the_altar,18,1
data "Justo en la mitad del puente, debe sostener algo importante."
data ambrosio,19,2
data "Ambrosio es un hombre de mediana edad, que te mira afable."
data the_torch,limbo,0
data "Está apagada."
data the_flags,28,1
data "Son las banderas britana y sajona. Dos dragones rampantes, rojo y blanco respectivamente, enfrentados."
data the_cloak,ulfius,0
data "Tu capa de general, de fina lana tintada de negro."
data the_waterfall,38,1
data "No ves nada por la cortina de agua. El lago es muy poco profundo."
data the_fallen_away,9,1
data "Muchas, inalcanzables rocas, apiladas una sobre otra."
data the_emerald,39,0
data "Es preciosa."
data the_sword,ulfius,0
data "Legado de tu padre, fiel herramienta en mil batallas."
data the_rags,limbo,0
data "Un trozo un poco grande de capa."
data the_thread,limbo,0
data "Un hilo se ha desprendido al cortar la capa con la espada."
data the_man,28,1
data "Es el jefe de los refugiados."
data the_idol,41,1
data "El ídolo tiene dos agujeros por ojos."
data the_lake,44,1
data "La luz entra por un resquicio, y caprichosos reflejos te maravillan."
data the_key,46,1
data "Una llave grande, de hierro herrumboso."
data the_flint,limbo,0
data "Se trata de una dura y afilada piedra."
data the_stone,18,0
data "Recia y pesada, pero no muy grande, de forma piramidal."
data the_door,47,1
data "Muy recia y con un gran candado."
data the_rocks,31,1
data "Son muchas, aunque parecen ligeras y con huecos entre ellas."
data the_snake,43,1
data "Una serpiente bloquea el paso al sur, corriendo a su lado el agua."
data the_log,15,0
data "Es un tronco recio, pero de liviano peso."
data the_piece,limbo,0
data "Es un poco de lo que antes era tu capa."
data the_lock,47,1
data "Está cerrado. Es muy grande y parece resistente."
defproc label_things_end:enddef
rem Acciones
rem Actions
rem datos: identificador de acción, sintaxis de la acción
rem data: action id,action syntax
defproc label_actions_start:enddef
data to_break,object_needed
data to_drop,object_needed
data to_examine,no_object_needed
data to_finish,no_object_needed
data to_fling,object_needed
data to_go_down,no_object_needed
data to_go_east,no_object_needed
data to_go_north,no_object_needed
data to_go_south,no_object_needed
data to_go_up,no_object_needed
data to_go_west,no_object_needed
data to_help,no_object_needed
data to_insert,object_and_complement_needed
data to_look,no_object_needed
data to_open,object_needed
data to_swim,no_object_needed
data to_take,object_needed
data to_speak,object_needed
defproc label_actions_end:enddef
rem Verbos
rem Verbs
rem datos: identificador de acción, verbo o sinónimo
rem data: action id,verb or synonym
defproc label_verbs_start:enddef
data to_break,"afila"
data to_break,"afilar"
data to_break,"ataca"
data to_break,"atacar"
data to_break,"corta"
data to_break,"cortar"
data to_break,"destroza"
data to_break,"destrozar"
data to_break,"empuja"
data to_break,"empujar"
data to_break,"golpea"
data to_break,"golpear"
data to_break,"mata"
data to_break,"matar"
data to_break,"recorta"
data to_break,"recortar"
data to_break,"rompe"
data to_break,"romper"
data to_break,"sacude"
data to_break,"sacudir"
data to_drop,"deja"
data to_drop,"dejar"
data to_drop,"desprenderse"
data to_drop,"despréndete"
data to_drop,"soltar"
data to_drop,"suelta"
data to_examine,"ex"
data to_examine,"examina"
data to_examine,"examinar"
data to_examine,"examinarte"
data to_examine,"examínate"
data to_examine,"i"
data to_examine,"mírate"
data to_finish,"acaba"
data to_finish,"acabar"
data to_finish,"fin"
data to_finish,"finaliza"
data to_finish,"finalizar"
data to_finish,"rendirse"
data to_finish,"ríndete"
data to_finish,"termina"
data to_finish,"terminar"
data to_fling,"arroja"
data to_fling,"arrojar"
data to_fling,"lanza"
data to_fling,"lanzar"
data to_fling,"tira"
data to_fling,"tirar"
data to_go_down,"abajo"
data to_go_down,"b"
data to_go_down,"baja"
data to_go_down,"bajar"
data to_go_down,"descender"
data to_go_down,"desciende"
data to_go_east,"e"
data to_go_east,"este"
data to_go_north,"n"
data to_go_north,"norte"
data to_go_south,"s"
data to_go_south,"sur"
data to_go_up,"arriba"
data to_go_up,"a"
data to_go_up,"ascender"
data to_go_up,"asciende"
data to_go_up,"sube"
data to_go_up,"subir"
data to_go_west,"o"
data to_go_west,"oeste"
data to_help,"auxilio"
data to_help,"ayuda"
data to_help,"ayudar"
data to_help,"ayúdame"
data to_help,"socorro"
data to_insert,"coloca"
data to_insert,"colócale"
data to_insert,"colocar"
data to_insert,"colocarle"
data to_insert,"introduce"
data to_insert,"introdúcele"
data to_insert,"introducir"
data to_insert,"introducirle"
data to_insert,"inserta"
data to_insert,"insértale"
data to_insert,"insertar"
data to_insert,"insertarle"
data to_insert,"mete"
data to_insert,"métele"
data to_insert,"meter"
data to_insert,"meterle"
data to_insert,"pon"
data to_insert,"ponle"
data to_insert,"poner"
data to_insert,"ponerle"
data to_insert,"situar"
data to_insert,"situarle"
data to_insert,"sitúa"
data to_look,"m"
data to_look,"mira"
data to_look,"mirar"
data to_look,"ojea"
data to_look,"ojear"
data to_open,"abre"
data to_open,"abrir"
data to_swim,"bañar"
data to_swim,"bañarse"
data to_swim,"bucea"
data to_swim,"bucear"
data to_swim,"báñate"
data to_swim,"nada"
data to_swim,"nadar"
data to_swim,"zambullirse"
data to_swim,"zambúllete"
data to_take,"agarra"
data to_take,"agarrar"
data to_take,"coge"
data to_take,"coger"
data to_take,"toma"
data to_take,"tomar"
data to_speak,"charla"
data to_speak,"charlar"
data to_speak,"comenta"
data to_speak,"comentar"
data to_speak,"comentarle"
data to_speak,"comentarlo"
data to_speak,"comentárselo"
data to_speak,"comunica"
data to_speak,"comunicar"
data to_speak,"comunicarle"
data to_speak,"comunicarlo"
data to_speak,"comunicárselo"
data to_speak,"comunícale"
data to_speak,"comunícalo"
data to_speak,"comunícate"
data to_speak,"coméntale"
data to_speak,"coméntalo"
data to_speak,"coméntaselo"
data to_speak,"comentárselo"
data to_speak,"conversa"
data to_speak,"conversar"
data to_speak,"decir"
data to_speak,"decirle"
data to_speak,"decirlo"
data to_speak,"decírselo"
data to_speak,"di"
data to_speak,"dile"
data to_speak,"dilo"
data to_speak,"díselo"
data to_speak,"habla"
data to_speak,"hablar"
data to_speak,"hablarle"
data to_speak,"háblale"
data to_speak,"háblalo"
data to_speak,"platica"
data to_speak,"platicar"
data to_speak,"platicarle"
data to_speak,"platicarlo"
data to_speak,"platicárselo"
data to_speak,"platícale"
data to_speak,"platícalo"
data to_speak,"pregunta"
data to_speak,"preguntar"
data to_speak,"preguntarle"
data to_speak,"preguntarlo"
data to_speak,"preguntárselo"
data to_speak,"pregúntale"
data to_speak,"pregúntalo"
defproc label_verbs_end:enddef
rem --------------------------------------------
rem Meta
deffn lines_between(procedure_1$,procedure_2$)
rem Devuelve el número de líneas de programa entre dos procedimientos o funciones.
rem Return the number of program lines between two procedure or functions.
loc line_step
let line_step=10
ret (lnum(procedure_2$)-lnum(procedure_1$))/line_step-1
enddef
defproc s
save_o "ayc_rendered_bas"
enddef
defproc fatal_error(message$)
ink #tw,red
print #tw,"Error fatal:"!message$
stop
enddef
defproc _debug(text$)
print #tw,"Punto de depuración:"!text$
enddef
Herramientas
Para automatizar la creación de los diversos ficheros en que el programa iba a distribuirse escribí dos sencillas herramientas que muestro también por si a alguien le sirven:
Dos simples llamadas al programa zip
reunidas en un ejecutable de Bash crean los ficheros ZIP y QLPAK:
#!/bin/sh
# ayc2media.sh
# Crea los ficheros ZIP y QLPAK del juego de QL "Asalto y castigo".
# Create the ZIP and QLPAK files of the QL game "Asalto y castigo".
# By Marcos Cruz (programandala.net)
# 2011-04-29 First version: QLPAK with MGE ROM, and ZIP.
# 2011-05-27 Added the qxl-es_kbt file.
# 2011-06-12 New QLPAK with JS ROM.
cd ~/ql/sb/ayc/media/content
zip -9 ../ayc.zip boot ayc_bas ext_display_code ext_inarray_code ext_megatk_code ext_minmax_code img_ayc8_scr iso8859-1_font qxl-es_kbt
zip -9 ../ayc_mge.qlpak boot ayc_bas ext_display_code ext_inarray_code ext_megatk_code ext_minmax_code img_ayc8_scr iso8859-1_font qxl-es_kbt mge.rom ayc_mge.qcf
zip -9 ../ayc_js.qlpak boot ayc_bas ext_display_code ext_inarray_code ext_megatk_code ext_minmax_code img_ayc8_scr iso8859-1_font qxl-es_kbt ayc_js.qcf
cd -
Un pequeño programa en SuperBASIC crea los ficheros WIN e IMG, según el emulador en que corra:
100 rem ayc2media_bas
110 rem Este programa crea los ficheros WIN e IMG del juego "Asalto y castigo".
120 rem This program creates the WIN and IMG files of the game "Asalto y castigo".
130 rem Copyright (C) 2011 Marcos Cruz (programandala.net)
140 rem Nota/Note:
150 rem Este fichero no usa el juego de caracteres de QL sino la codificación estándar ISO 8859-1.
160 rem This file doesn't use the QL charset but a standard ISO 8859-1 encoding.
170 rem Historial:
180 rem 2011-04-24 Primera versión, solo para QPC2 y ficheros WIN.
190 rem 2011-04-27 Primer borrador de versión dual para QPC2 y Q-emuLator.
200 rem 2011-04-29 Primera versión dual funcional.
210 rem 2011-05-02 Nuevo fichero "qxl-es_kbt"; fichero "iso8859-1_font" renombrado; cambios en los textos; control de errores para detectar nombres de fichero demasiado largos; ventana propia.
220 rem 2011-05-08 Nuevo procedimiento win_label para modificar la etiqueta interna de un fichero WIN (que no es posible cambiar al formatear y que QPC2 crea con el nombre del dispositivo).
230 rem 2011-07-17 Ahora resulta que win_label borra el contenido del fichero win (!?). Parece que no ocurre si la operación se hace manualmente tras haber montado el fichero en otra sesión del emulador.
240 tk2_ext
250 init_the_window
260 print #win,"ayc2media"\\
270 create_the_media
280 print #win,"Tarea terminada."
290 close #win
300 stop
310 defproc init_the_window
320 let win=fopen("con_512x256a0x0")
330 paper #win,0
340 ink #win,7
350 csize #win,2,0
360 cls #win,0
370 border #win,8
380 enddef
390 defproc create_the_media
400 if ver$="HBA"
410 qpc2_media
420 else
430 qemulator_media
440 endif
450 enddef
460 defproc qpc2_media
470 loc dev1$
480 print #win,"Se va a crear un nuevo fichero ayc.win."
490 prompt
500 win_drive 8,"q:\sb\ayc\media\ayc.win"
510 win_format 8,1
520 format win8_1
530 print #win,"Se ha creado y formateado el fichero ayc.win."
540 dev_use 1,"dos1_sb_ayc_media_c_"
550 copy_ayc "dev1_","win8_"
560 dev_use 1,dev1$
570 win_drive 8,"noone":rem fichero inexistente, para liberar el actual / unexistant file, just to free the current one
580 win_label "dos1_sb_ayc_media_ayc.win","ayc"
590 enddef
600 defproc win_label(win_file$,label$)
610 loc channel
620 let label$=label$(to 20)
630 let channel=fopen(win_file$):ert channel
640 wput #channel\4,len(label$)
650 bput #channel\6:print #channel,label$
660 close #channel
670 enddef
680 defproc qemulator_media
690 loc data_dir$
700 print #win,"Inserta el siguiente directorio:"
710 print #win,"- Q:\ (~/ql/) en la ranura 2."
720 print #win,"Inserta los siguientes ficheros:"
730 print #win,"- ayc.win en la ranura 7."
740 print #win,"- ayc.flp en la ranura 8."
750 prompt
760 format flp8_ayc
770 print #win,"Se ha formateado el fichero ayc.img."
780 let data_dir$=datad$
790 data_use "mdv2_sb_ayc_"
800 copy_ayc "media_c_","win7_"
810 copy_ayc "media_c_","flp8_"
820 data_use data_dir$
830 enddef
840 defproc prompt
850 print #win,\"Pulsa una tecla para continuar."
860 pause
870 enddef
880 defproc copy_ayc(from_dev$,to_dev$)
890 loc file$
900 print #win,\"Copiando de "&from_dev$&" a "&to_dev$&"..."
910 rem when err
920 rem ert ernum
930 rem endwhen
940 restore
950 rep copying
960 read file$
970 print #win,file$
980 if not len(file$):exit copying
990 copy_o from_dev$&file$,to_dev$&file$
1000 endrep copying
1010 when err
1020 endwhen
1030 enddef
1040 data "boot"
1050 data "ayc_bas"
1060 data "ext_display_code"
1070 data "ext_inarray_code"
1080 data "ext_megatk_code"
1090 data "ext_minmax_code"
1100 data "img_ayc8_scr"
1110 data "iso8859-1_font"
1120 data "qxl-es_kbt"
1130 data "":rem fin de datos / end of data