Bandera negra [en Sinclair BASIC]

Descripción del contenido de la página

Juego de simulación y aventuras para ZX Spectrum, escrito en Sinclair BASIC con el formato de BASin.

Proyecto abandonado. Iniciado en 2011-08-02. 20% completado.

Etiquetas:

Para esta primera versión frustrada de Bandera negra tomé como base el código del programa original Jolly Roger y lo convertí al formato de BASin, el veterano entorno de desarrollo de Sinclair BASIC para Windows (en mi caso, ejecutado en Debian con ayuda de Wine).

El formato propio de BASin permite editar el código fuente con cualquier editor de texto, escribir metacomentarios, usar una notación nemónica para los códigos de los caracteres propios de la ZX Spectrum y usar etiquetas en las referencias a los números de línea. Esto compensaba en parte las muchas carencias del lenguaje original.

La plataforma de ejecución elegida (mediante el emulador Fuse) era:

La reescritura y comentado del código original para hacerlo más legible y así facilitar la traducción y las modificaciones progresaron rápidamente. Pero cuando los cambios en el código estaban muy avanzados, un error de BASin en la traducción de las etiquetas me hizo desistir. Era un fallo imposible de arreglar porque el autor, con quien me puse en contacto al respecto, había abandonado el programa en favor de un proyecto más moderno y ambicioso: SpecBAS.

El código de esta frustrada versión en Sinclair BASIC sirvió de base para la versión posterior en MasterBASIC.

Código fuente

La última versión del programa principal no puede ser ejecutada sin modificar las fuentes porque como se ha explicado BASin no traduce diversas etiquetas. No obstante muestro el listado del programa principal y de otros dos auxiliares que fueron escritos directamente en el emulador.

zonesMaker

Este pequeño programa herramienta graba en el disquete zonas de atributos de la pantalla, que serán utilizadas para hacer borrados y otros efectos de pantalla durante el juego. El cargador del juego copia estos ficheros al disco RAM de la ZX Spectrum 128, para poder acceder a ellos rápidamente durante el juego.

  10 REM zonesMaker - Programa herramienta de
  20 REM "Bandera negra"
  30 REM Crea ficheros en disquete con bloques de atributos.
  40 REM (C) 2011 Marcos Cruz (programandala.net)
  50:
  60 REM 2010-08-05 Primera version
  70:
  80 CLS #
  90 POKE @0,0
 100 CLOSE #*
 110 ERASE d*"zonesList"
 120 OPEN #4;d1"zonesList"RND
 130:
 140 LET p=0: LET i=0: LET b=0: LET l=20: GO SUB 340
 150 LET p=0: LET i=0: LET b=0: LET l=6: GO SUB 340
 160 LET p=0: LET i=0: LET b=1: LET l=6: GO SUB 340
 170 LET p=0: LET i=0: LET b=0: LET l=4: GO SUB 340
 180 LET p=0: LET i=0: LET b=1: LET l=4: GO SUB 340
 190 LET p=1: LET i=1: LET b=0: LET l=13: GO SUB 340
 200 LET p=1: LET i=1: LET b=1: LET l=13: GO SUB 340
 210 LET p=5: LET i=5: LET b=0: LET l=3: GO SUB 340
 220 LET p=5: LET i=5: LET b=1: LET l=3: GO SUB 340
 230 LET p=6: LET i=6: LET b=0: LET l=5: GO SUB 340
 240 LET p=6: LET i=6: LET b=1: LET l=5: GO SUB 340
 250 LET p=6: LET i=6: LET b=0: LET l=13: GO SUB 340
 260 LET p=6: LET i=6: LET b=0: LET l=18: GO SUB 340
 270:
 280 CLS #
 290 CLOSE #*4
 300 PRINT "Lista de ficheros creados:"
 310 MOVE d*"zonesList" TO #2
 320 STOP
 330:
 340 REM Subrutina
 350 REM Entrada: p,i,b,l
 360 LET f$="zp"+STR$ p+"i"+STR$ i+"b"+STR$ b+"l"+("0" AND (10 > l))+STR$ l
 370 PRINT : REM Esto inexplicablemente evita un curioso problema en Beta DOS: sin esto, la impresion en el disco incluye los caracteres de control de los atributos actuales. No se arregla de otra forma.
 380 BORDER p: PAPER p: INK i: BRIGHT b: CLS
 390 SAVE OVER d*;f$CODE 22528,l*32
 400 PRINT #4;f$
 410 RETURN
 420:
 430 SAVE OVER d*"zonesMaker"

Cargador

El cargador copia los ficheros de atributos de pantalla desde el disquete al disco RAM, utilizando el listado creado por zonesMaker en el fichero de datos zonesList:

  10 REM Cargador para
  20 REM "Bandera negra"
  30 REM (C) 2011 Marcos Cruz (programandala.net)
  40:
  50 REM 2011-08-05 Primera version
  60 REM 2011-08-06 Las zonas de color se leen de un fichero secuencial. Subrutinas.
  70 REM 2011-08-08 Incluida una pantalla. Reescrita una subrutina para evitar codigo duplicado.
  80:
  90 CLS #: BORDER 0: PAPER 0 : INK 7
 100 CLEAR 32767
 110:
 120 REM Pantalla de presentacion
 130:
 140 REM LOAD d*"jr1" SCREEN$ : REM provisional
 150 SAVE !"tmpScreen"SCREEN$
 160:
 170 REM Copiar al disco RAM las zonas de color cuyos ficheros fueron creados por el programa zonesMaker:
 180:
 190 DEF FN e(x)=USR 8: REM Fin de fichero en Beta DOS
 200 CLOSE #*4
 210 OPEN #4;d*"zonesList"RND
 220 IF FN e(4) THEN  GO TO 250
 230 INPUT #4;f$
 240 GO SUB 460: GO TO 220
 250 CLOSE #*4
 260:
 270 REM Copiar al disco RAM los juegos de caracteres y de graficos
 280:
 290 LET length=768: LET address=USR "a"-length
 300 LET f$="jr3": GO SUB 510
 310 LET f$="jr4": GO SUB 510
 320 LET f$="esRomChr": GO SUB 510
 330 LET length=168: LET address=USR "a"
 340 LET f$="jr6": GO SUB 510
 350 LET f$="bnUDG1": GO SUB 510
 360:
 370 REM Copiar al disco RAM las pantallas
 380:
 390 LET f$="scroll3": LET address=32768: LET lenght=6912: GO SUB 510
 400:
 410 REM Cargar el programa principal
 420:
 430 CLEAR USR "a"-768-1
 440 LOAD d*"bn2"
 450:
 460 REM Subrutina: cargar del disquete un fichero de zona de atributos y copiarlo al disco RAM
 470 REM Entrada: f$=fichero
 480:
 490 LET address=32768: LET length=VAL f$(LEN f$-1 TO )*32
 500:
 510 REM Subrutina: cargar del disquete un fichero de caracteres o UDG y copiarlo al disco RAM
 520 REM Entrada: f$,address,length
 530:
 540 LOAD d*;f$CODE address
 550 SAVE !f$CODE address,length
 560 RETURN
 570:
 580 SAVE  OVER d*"bn0" LINE 10


Programa principal

gosub @romCharset:stop:rem Debug
rem "Bandera negra" (version A-20110811, en desarrollo)
rem Juego de simulación para ZX Spectrum 48
rem Copyright (C) 2011 Marcos Cruz (programandala.net)
rem Version traducida y remozada de "Jolly Roger", Copyright (C) 1984 bJones / Video Vault ltd.

################################################
# Acerca de este fichero

# Este programa escrito en Sinclair BASIC está en el formato
# BAS del entorno de desarrollo BASin y para editarlo se
# ha usado el editor Vim con la codificación Latin1.

# Procedimiento de trabajo que se ha seguido: Con BASin se
# lee el código fuente y se exporta a un fichero TAP con la
# herramienta provista para ello (Tape Image Builder).  El
# TAP se abre y carga en el emulador de ZX Spectrum y el
# programa se graba en la imagen de disquete de DISCiPLE/+D
# que contiene todos los ficheros del programa.

# Atención:
# Si BASin graba este programa de nuevo en formato BAS
# elimina los comentarios internos
# (las líneas que comienzan con el signo «#», que
# no forman parte del código en Sinclair BASIC).

################################################
# Tareas pendientes

# Eliminar el cálculo inicial del contenido de la matriz b().
# Se puede hacer en cada ocasión antes de desembarcar.

# Hay dos cálculos de daños del barco: tormenta y arrecifes. ¿Unificar en subrutina?

# Cambiar la medida del daño del barco (variable «damage»)
# por su estado, analógamente a la tripulación, y mostrarlo
# en forma de texto.

# Usar PAUSE en vez de bucles para las pausas que usan IF LEN INKEY$.

# Tabla de mejores puntuaciones; guardada en disquete.

# Hacer dos aspectos para el final: éxito y fracaso.

# Ampliar fn l$() y usarla en la negociación.

# Un programe herramienta que prepare y guarde las matrices
# en el disquete, para que el juego se ahorre la tarea, el
# código y el tiempo. (Quizá no merece la pena, porque hay
# variables que definir también y deberían duplicarse en
# ambos programas).

# Hacer que el número de doblones hallados varíe.

# Usar un juego de caracteres diferente para las palabras de
# los nativos.

# Hacer, si no está, que se reciban provisiones, munición y
# tropa tras vencer a un barco.

# Dibujar escorpión y pantano.

# Poder matar escorpión.

# Borrar serpiente y escorpión cuando mueran.

# Hacer variable el dibujo de provisiones.

# Poner la pista en el bocadillo.

# Reducir moral unas décimas cuando un hombre sea herido o
# muerto.

# Reducir la energía un número proporcional a la gravedad
# del ataque, no siempre 1.

# Informar de que no se puede desembarcar
# porque la isla ya ha sido visitada.

# Fallo: el barco sale con fondo negro cuando encalla.

# Revisar los rangos de doblones al comerciar.

# Informar de si hay muertos cuando el bote es alcanzado por
# error. Calcular 'alive' antes y después de herir a los
# hombres.

# Hacer el informe de tripulación accesible también en
# tierra.

# Justificar a la derecha los números del informe.

# Escribir una variante de la rutina de impresión de
# párrafos, para usar en el panel. (Unas variables pueden
# servir para cambiar la primera columna y el ancho de la
# rutina actual).

# Simplificar y embellecer el panel de control.

# Unificar el panel de control en tierra y en mar.

# Usar otro juego de caracteres.

# Embellecer tabla de puntuación final.

# Poner el informe de estado en la pantalla, no en el panel.

# Hacer que se muestre el nombre al anunciar la muerte de un
# tripulante (línea @chooseDeadOne, eventos hacia @islandEvents).

# Hacer que el jugador pueda poner nombre a los miembros de
# la tripulación.

# Que no aparezcan los comandos que no puedan usarse en cada
# situación.

# Cambiar el aspecto de las pantallas finales: negras y con calaveras.

# Hacer que el jugador pueda elegir nombre al capitán.

# Añadir Fin a la lista de comandos

# Al embarcar, borrar panel antes de redibujar pantalla.

# Quitar el cartel con el nombre sobre la isla del tesoro;
# usar el panel.

# Hacer que el sol se imprima también al azar, pero no
# coincida con las nubes.

################################################
# Ficheros

# Los juegos de caracteres y de gráficos han sido copiados
# del disquete al disco RAM por el programa cargador y se
# cargan en memoria cuando se necesitan.

    let charset=usr "a"-val "768":\
    gosub @ramCharset:\
    gosub @udg1

################################################
# Funciones

# Dirección de los atributos de pantalla del primer carácter de una línea:
    def fn a(l)=val"22528"+l*cpl

# «doblón» o «doblones» según la cantidad:
    def fn d$(c)="dobl"+("ones" and (c> n1))+((o$+"n") and (c=n1))+"."

# Número en letra, para números de 1 a 5:
#def fn l$(n)=("un"and (n=n1))+("dos"and (n=n2))+("tres"and (n=n3))+("cuatro"and (n=n4))+("cinco"and n=n5))
#def fn l$ (n)="undostrescuatrocinco"(code(chr$ 1+chr$ 3+chr$ 6+chr$ 10+chr$ 15(l)) to code(chr$ 2+chr$ 5+chr$ 9+chr$ 15+chr$ 20)(l))
    def fn l$(n)=("     un    dos   tres  cuatrocinco"(l*6) to code(chr$ 8+chr$ 15+chr$ 21+chr$ 29+chr$ 34)(l)))and (l<6)+(str$ l and(l>5))

# Una letra en vídeo inverso:
    def fn v$(l$)=chr$ 20+chr$ 1+l$+chr$ 20+chr$ 0

# Una opción del panel, activa o inactiva:
    def fn o$(o$,l,a)=o$ and not a+(o$(to l-1)fn v$(o$(l)+o$(l+1 to) and a

# Un texto $ centrado en una línea:
    def fn c$(l,t$)=chr$ 22+chr$ l+chr$ ((cpl-len t$)/2)+t$

# Nombre de un tripulante, sin espacios al final:
    def fn n$(m)=d$(m,2 to code(d$(m,1)))

# Cantidad completa de doblones:
    def fn q$(n)=fn l$(n)+" "+fn d$(n)

# Una cadena con la primera letra mayúscula (no se
# comprueba):
    def fn u$(t$)=chr$(code t$(1)-32)+t$(2 to)

################################################
# Constantes

# Números más habituales:
    let n0=not pi:let n1=sgn pi:let n2=val "2":let n3=int pi:let n4=val "4":let n5=val "5":let n6=val "6":let n7=val "7":let n8=val "8":let n9=val "9":let n10=val "10":let n32=code" "

# Vocales minúsculas acentuadas:
    let a$="#":let e$="$":let i$="%":let o$="&":let u$="'"
# Eñe minúscula y aperturas de interrogación y admiración:
    let n$="|":let q$="]":let x$="["

# Línea en blanco:
    let l$="                                "
# «capitán»:
    let c$="capit"+a$+"n"
# Nombre de la isla, provisional!!!:
    let t$="Calavera"
# Caracteres por línea:
    let cpl=n32
# Nombre del barco, provisional!!!:
    let b$="Furioso"

################################################
# Inicio

@start:

    gosub @intro:\
    gosub @init:\
    cls

################################################
# En el barco

@aboard:

    goto @scenery

################################################
# Subrutina
# Dibujar el mar y el barco

@seaAndShip:

    gosub @seaAndSky:\
    goto @drawShipUp

################################################
# Selección de comando a bordo

# Ojo!!! El bloque en @scenery salta aquí.

@shipCommand:

    for w=n1 to val "80"

    let k=code inkey$
# "n" o arriba:
    if k=110 or k=11 then goto @seaNorth
# "s" o abajo:
    if k=115 or k=n10 then goto @seaSouth
# "e" o derecha:
    if k=101 or k=n9 then goto @seaEast
# "o" o izquierda:
    if k=111 or k=n8 then goto @seaWest
# "i":
    if k=105 then gosub @report
# "a":
    if k=97 then goto @attackShip
# "t":
    if k=116 then gosub @crewReport
# "d":
    if k=100 then goto @disembarkIfPossible
# "F":
    if k=70 then beep .3,30: goto @theEnd

# Cabeceo del barco:
    if w=40 then gosub @drawShipDown
    if w=80 then gosub @drawShipUp

    next w

# ¿Tormenta?:
    if (int (rnd*n10)+n1)=n2 then gosub @storm

    goto @shipCommand

################################################
# Norte en el mar

@seaNorth:

    if a(sPos+15)=n1 then goto @runAground
    let sPos=sPos+15: goto @scenery

################################################
# Sur en el mar

@seaSouth:

    if a(sPos-15)=n1 then goto @runAground
    let sPos=sPos-15: goto @scenery

################################################
# Este en el mar

@seaEast:

    if a(sPos+n1)=n1 then goto @runAground
    let sPos=sPos+n1: goto @scenery

################################################
# Oeste en el mar

@seaWest:

    if a(sPos-n1)=n1 then goto @runAground
    let sPos=sPos-n1: goto @scenery

################################################
# Subrutina
# No se puede hacer eso

@impossible:

    gosub @spanishCharset: gosub @wipePanel
    print at 18,n2; paper n0;"Lo siento, capit";a$;"n,";at 19,n2;"no puede hacer eso."
    rem goto @pause300

################################################
# Desembarcar

@disembarkIfPossible:

    gosub @spanishCharset

# depuración!!!:
#let a(sPos)=treasureIsland

# Ojo!!! Aparente error del original,
# que impedia la escena de desembarco del bote
# en la isla del tesoro:

#if b(sPos)=n1 then goto @disembark
#if a(sPos)=treasureIsland then goto @enterTreasureIsland

# Error corregido:
    if b(sPos)=n1 or a(sPos)=treasureIsland then goto @disembark

# Ojo!!! Comprobar la lógica del salto aquí:
@impossibleAttack:

    gosub @impossible
    gosub @shipPanel:goto @shipCommand

@disembark:

    let supplies=supplies-(int (rnd*n2)+n1):\
    gosub @wipePanel:\
    gosub @seaAndSky

# Dibujar escena de desembarco:
    gosub @graphicCharset1
    print at n8,31; ink n4; paper n1;":";at n9,27;"HI :";at n10,25;"F";at 11,23;"JK"
    for z=n0 to val "20":\
        print at 11,z; ink n6; paper n1;" <>":\
        PAUSE n10:\
    next z

    if a(sPos)=treasureIsland then goto @enterTreasureIsland

# Crear mapa de la isla:
    gosub @islandMap

    goto @enterIslandLocation

################################################
# Comerciante nativo

@nativeTrader:

    gosub @graphicCharset1
    for z=n3 to val "15": print at z,n0; ink n0; paper n6;l$: next z
    gosub @drawNative
    ink n0
    plot 100,100: draw 20,n10: draw n0,30: draw n2,n2: draw 100,n0: draw n2,-n2: draw n0,-60: draw -n2,-n2: draw -100,n0
    draw -n2,n2: draw n0,20: draw -20,n0
    ink n7
    let p=n4: let q=n4: gosub @palm2At
    gosub @wipePanel
    gosub @spanishCharset
    print at panelTop+n1,n3; paper n0;"Comerciante nativo"
    ink n0:let t$=x$+"Hola. Yo vender a t"+u$+"pista para tesoro.":gosub @nativeTell
    gosub @wipeNativeWords
    let price=int (rnd*n5)+n6
    print at n6,16; ink n0; paper n6;"Precio";at n7,16;"ser...";at n8,16;price;" ";fn d$(price);"."
    gosub @wipeNativeWords
    print at n6,16; ink n0; paper n6;q$+"Qu"+e$;at n7,16;" ofrecer t"+u$+",";at n8,16;"blanco?"
    print at 18,n3; paper n0;q$+"Qu"+e$+"oferta le haces?";at 19,n3;"Tienes ";fn l$(cash);" ";fn d$(cash);"."
    gosub @getOffer

    beep .2,n10: print at 18,14; paper n0;offer;" ";fn d$(offer);"."
    if offer>=price or offer=price-n1 then goto @acceptedOffer
    if offer<=(price-n4) then goto @rejectedOffer
    let z=int (rnd*n4)+n1
    if z=n1 then goto @L3400
    if z=n2 then goto @L3430
    gosub @wipeNativeWords: print at n6,16; ink n0; paper n6;x$;"Yo querer";at n7,16;"m";a$;"s!";at n5,19;x$;"No!";at n10,16;price-n1;" ";fn d$(price-n1);"."

@L3150:

    beep .2,n10: print at 18,14; paper n0;"1 to 9.      "
    gosub @getOffer

    beep .2,n10: print at 18,14; paper n0;offer;" ";fn d$(offer);"."
    if offer>=(price-n2) then goto @acceptedOffer
    if offer<(price-n2) then goto @rejectedOffer
    gosub @spanishCharset

@L3400:

    gosub @wipeNativeWords: let price=int (rnd*n6)+n3: print at n6,16; ink n0; paper n6;"T";u$;" darme";at n7,16;"um...";at n9,16;price;" ";fn d$(price);"."
    beep .2,n10: print at 18,14; paper n0;"de 1 a 9      ": gosub @getOffer:
    beep .2,n10: print at 18,14; paper n0;offer;" ";fn d$(offer);"."
    if offer>=price then goto @acceptedOffer
    if offer<price then goto @rejectedOffer

@L3430:

    gosub @wipeNativeWords: let price=int (rnd*n6)+n3: print at n6,16; ink n0; paper n6;price;" ";fn d$(price);at n7,16;" ser";at n8,16;"precio bueno";at n10,16;"rostro p";a$;"lido."
    goto @L3150

################################################
# Subrutina
# Recibe la oferta del jugador (1-9)

@getOffer:

    pause n0
    let offer=code inkey$-code "0"
    if offer<n1 or offer>n9 then beep .1,n10: goto @getOffer
    return

################################################
# Oferta rechazada

@rejectedOffer:

    gosub @pause200
    gosub @wipeNativeWords
    print ink n0;paper n6;\
    at n6,16;x$;"Ser insulto!";\
    at n8,16;x$;"Fuera de";\
    at n9,16;"isla m";i$;"a!"
    gosub @wipeNativeWords

################################################
# Embarcar

@backToTheShip:

    let b(sPos)=n0:\
    let day=day+n1:\
    goto @aboard

################################################
# Oferta aceptada

@acceptedOffer:

    gosub @wipeNativeWords
    print ink n0;paper n6;\
    at n6,17;"  Ug...";\
    at n9,16;" Um... Pista..."
    gosub @wipePanel
    randomize
    print at 17,14; ink n0; paper n4;"Pista."
    let clue=int (rnd*n6)+n1
    if clue=n1 then print at 19,n1; paper n0;"Tomar camino ";path
    if clue=n2 then print at 19,n1; paper n0;"Girar en ";a$;"rbol ";tree
    if clue=n3 then print at 19,n1; paper n0;"Ir ";h$(ect);" en ";a$;"rbol."
    if clue=n4 then print at 19,n1; paper n0;"Atravesar poblado ";at 20,n10;f$(village)
    if clue=n5 then print at 19,n1; paper n0;"Ir ";g$(dir);" desde poblado."
    if clue=n6 then print at 19,n1; paper n0;"Dar ";pace;" paso";"s" and (pace>n1);" desde poblado."
    gosub @pause100
    gosub @wipeNativeWords: print at n6,17; ink n0; paper n6;"Entrar";at n7,16;"caminando hasta";at n9,16;" isla de";at n10,16;" tesoro."
    gosub @pause600
    let cash=cash-offer:\
    let score=score+val "200":\
    let trade=trade+n1
    goto @backToTheShip

################################################
# Comerciar

@trade:

    if c(iPos)=nativeVillage then goto @nativeTrader
    gosub @impossible:\
    gosub @wipePanel:\
    gosub @islandPanel:goto @islandCommand

################################################
# Subrutina
# Borrar palabras del nativo

@wipeNativeWords:

    gosub @pause50
    for z=n1 to val "500":\
        if len inkey$ then goto @wipeNativeWords01
    next z

@wipeNativeWords01:

    paper n6:\
    for z=n5 to val "11":\
        print at z,16;"            ":\
    next z
    beep .15,int (rnd*n10)+11
    return

################################################
# Selección de comando en tierra

@islandCommand:

    let k=code inkey$
# "n" o arriba:
    if k=110 or k=11 then goto @islandNorth
# "s" o abajo:
    if k=115 or k=n10 then goto @islandSouth
# "e" o derecha:
    if k=101 or k=n9 then goto @islandEast
# "o" o izquierda:
    if k=111 or k=n8 then goto @islandWest
# "c":
    if k=99 then goto @trade
# "b":
    if k=98 then goto @backToTheShip
# "i":
    if k=105 then gosub @report
# "m":
    if k=109 then gosub @attack
# "t":
    if k=116 then gosub @crewReport
# "F":
    if k=70 then beep .3,30: goto @theEnd
    goto @islandCommand

################################################
# Norte en tierra

@islandNorth:

    if c(iPos+n6)=n1 then goto @islandCommand
    let iPos=iPos+n6:\
    goto @enterIslandLocation

################################################
# Sur en tierra

@islandSouth:

    if c(iPos-n6)=n1 then goto @islandCommand
    let iPos=iPos-n6:\
    goto @enterIslandLocation

################################################
# Este en tierra

@islandEast:

    if c(iPos+n1)=n1 then goto @islandCommand
    let iPos=iPos+n1:\
    goto @enterIslandLocation

################################################
# Oeste en tierra

@islandWest:

    if c(iPos-n1)=n1 then goto @islandCommand
    let iPos=iPos-n1

################################################
# Entrar en un escenario de la isla

@enterIslandLocation:

    gosub @wipePanel:\
    gosub @drawIslandScenery:\
    gosub @spanishCharset

    if c(iPos)=snake then \
        gosub @manInjured:\
        print at 19,n1; paper n0;"Una serpiente ha mordido a ";fn n$(injured);".":\
        goto @enterIslandLocation00

    if c(iPos)=nativeFights then \
        gosub @manInjured:\
        print at 19,n1; paper n0;"Un nativo intenta bloquear el paso y hiere a ";fn n$(injured);".":\
        goto @enterIslandLocation00

    if c(iPos)=dubloonsFound then \
        let dub=int (rnd*n2)+n1:\
        print at 19,n1; paper n0;"Encuentras ";fn l$(dub);" ";fn d$(dub);".":\
        let cash=cash+dub:\
        gosub @drawDubloons:\
        let c(iPos)=n4:\
        goto @enterIslandLocation00

    if c(iPos)=nativeAmmo then \
        print at 19,n1; paper n0;"Un nativo te da algo de munici";o$;"n":\
        let ammo=ammo+n1:\
        let c(iPos)=nativeFights:\
        goto @enterIslandLocation00

    if c(iPos)=nativeSupplies then \
        print at 19,n1; paper n0;"Un nativo te da provisiones.":\
        let supplies=supplies+n1:\
        let c(iPos)=nativeFights:\
        goto @enterIslandLocation00

    if c(iPos)=nativeVillage then \
        print at 19,n1; paper n0;"Descubres un poblado nativo."

    # falta crear constantes para estos casos!!!
    if c(iPos)=n4 or c(iPos)=n6 then \
        gosub @islandEvents

@enterIslandLocation00:

    gosub @graphicCharset1
    for z=n1 to val "300":\
        if len inkey$ then goto @enterIslandLocation01
    next z

@enterIslandLocation01:

    gosub @checkTheEnd:\
    gosub @islandPanel:goto @islandCommand

################################################
# Subrutina
# Eventos especiales en la isla

@islandEvents:

    let event=int (rnd*11)+n1


    if event=n1 then \
        print at 19,n1; paper n0;"  Uno de la tripulaci";o$;"n se hunde ";at 20,n10;"en arenas movedizas.":\
        gosub @chooseDeadOne:\
        return

    if event=n2 then \
        print at 19,n1; paper n0;"  Uno de la tripulaci";o$;"n se hunde ";at 20,n10;"en un pantano.":\
        gosub @chooseDeadOne:\
        return

    if event=n3 then \
        gosub @manInjured:\
        print at 19,n1; paper n0;"A ";fn n$(injured);" le muerde";at 20,n7;"una ara";n$;"a.":\
        return

    if event=n4 then \
        gosub @manInjured:\
        print at 19,n1; paper n0;"A ";fn n$(injured);" le pica";at 20,n7;"un escorpi";o$;"n.":\
        return

    if event=n5 then \
        print at 19,n1; paper n0;"La tripulaci";o$;"n est";a$;" hambrienta.":\
        let morale=morale-n1:\
        return

    if event=n6 then \
        print at 19,n1; paper n0;"La tripulaci";o$;"n est";a$;" sedienta.":\
        let morale=morale-n1:\
        return

    if event=n7 then \
        let dub=int (rnd*n4)+n2:print at 19,n1; paper n0;"Encuentras ";fn l$(dub);" ";fn d$(dub);".":\
        let cash=cash+dub:\
        gosub @drawDubloons:\
        return

    if event=n8 then \
        print at 19,n1; paper n0;"Sin novedad, ";c$;".":\
        return

    if event=n9 or event=n10 then \
        print at 19,n2; paper n0;"La costa est";a$;" despejada, ";c$;".":\
        return

    if event=val "11" then \
        print at 19,n1; paper n0;"Sin novedad, ";c$;"."

    return

################################################
# Subrutina
# Dibujar escenario de la isla

@drawIslandScenery:

    load!"zp6i6b0l13"code fn a(n3)
    gosub @sunnySky
    if c(iPos-n6)=coast then gosub @drawBottomWaves
    if c(iPos+n6)=coast then gosub @drawHorizontWaves
    if c(iPos-n1)=coast then gosub @drawLeftWaves
    if c(iPos+n1)=coast then gosub @drawRightWaves
    if c(iPos)=nativeVillage then gosub @drawVillage
    if c(iPos)=dubloonsFound then \
        let p=n8:let q=n4:gosub @palm2At:\
        let p=n5:let q=14:gosub @palm2At
    if c(iPos)=nativeFights then \
        let p=n5:let q=14:gosub @palm2At:\
        let p=n8:let q=25:gosub @palm2At:\
        gosub @drawNative
    if c(iPos)=n4 then \
        let p=n8:let q=25:gosub @palm2At:\
        let p=n8:let q=n4:gosub @palm2At:\
        let p=n5:let q=16:gosub @palm2At
    if c(iPos)=snake then \
        let p=n5:let q=13:gosub @palm2At:\
        let p=n6:let q=n5:gosub @palm2At:\
        let p=n8:let q=18:gosub @palm2At:\
        let p=n8:let q=23:gosub @palm2At:\
        gosub @drawSnake
    if c(iPos)=n6 then \
        let p=n8:let q=23:gosub @palm2At:\
        let p=n5:let q=17:gosub @palm2At:\
        let p=n8:let q=n4:gosub @palm2At
    if c(iPos)=nativeSupplies then \
        gosub @drawSupplies:\
        gosub @drawNative:\
        let p=n4:let q=16:gosub @palm2At
    if c(iPos)=nativeAmmo then \
        gosub @drawAmmo:gosub @drawNative:\
        let p=n5:let q=20:\
        gosub @palm2At
    return

################################################
# Subrutina
# Dibujar olas en el horizonte

@drawHorizontWaves:

    print at n3,n0; ink n7; paper n1;"  kl  mn     nm    klk   nm nm n":\
    return

################################################
# Subrutina
# Dibujar olas en primer plano

@drawBottomWaves:

    print at 14,n0; paper n1; ink n7;"  kl     mn  mn    kl    kl kl  m     mn      klmn   mn m  mn   ":\
    return

################################################
# Subrutina
# Dibujar olas a la izquierda

@drawLeftWaves:

    for z=n3 to 15:\
        print at z,n0; ink n7; paper n1;"  ":\
    next z
    print at n6,n0; ink n7; paper n1;"mn";at n10,n0;"kl";at 13,n0;"k";at n4,n0;"m";at n8,n1;"l"
    if c(iPos+n6)<>n1 then \
        gosub @graphicCharset2:\
        print at n3,n2; ink n6; paper n1;"A":\
        gosub @graphicCharset1
    if c(iPos+n6)=n1 then \
        gosub @graphicCharset2:\
        print at n4,n2; ink n6; paper n1;"A":\
        gosub @graphicCharset1
    if c(iPos-n6)=n1 then \
        gosub @graphicCharset2:\
        print at 13,n2; ink n6; paper n1;"C":\
        gosub @graphicCharset1
    return

################################################
# Subrutina
# Dibujar olas a la derecha

@drawRightWaves:

    for z=n3 to val "15":\
        print at z,30; ink n7; paper n1;"  ":\
    next z
    print at n6,30; ink n7; paper n1;"mn";at n10,30;"kl";at 13,31;"k";at n4,30;"m";at n8,31;"l"
    if c(iPos+n6)=n1 then \
            gosub @graphicCharset2:\
            print at n4,29; ink n6; paper n1;"B":\
            gosub @graphicCharset1
    if c(iPos-n6)=n1 then \
            gosub @graphicCharset2:\
            print at 13,29; ink n6; paper n1;"D":\
            gosub @graphicCharset1
    if c(iPos+n6)<>n1 then \
            gosub @graphicCharset2:\
            print at n3,29; ink n6; paper n1;"B":\
            gosub @graphicCharset1
    return

################################################
# Subrutina
# Dibujar poblado

@drawVillage:

    gosub @graphicCharset2
    print at 11,n4; ink n4; paper n6;"ST    ST ST  ST ST"
    print at 12,n4; ink n4; paper n6;"VUW  4 VUW 78  VUW VUW"
    print at n8,n4; ink n4; paper n6;"ST   ST    ST ST  ST "
    print at n9,n4; ink n4; paper n6;"VUW   VUW  4 VUW VUW  VUW"
    print at n5,n6; ink n4; paper n6;" ST    ST   ST";at n6,n6;" VUW    78   VUW   4"
    print at 12,n7; ink n0; paper n6;"X";at 12,17;"Y";at 12,22;"Z";at 12,26;"XY"
    print at n9,n8; ink n0; paper n6;"ZZ";at n9,13;"Y";at n9,24;"ZX";at n6,n10;"XYZ";at n6,17;"YX";at n6,26;"Z"
    gosub @graphicCharset1
    return

################################################
# Subrutina
# Dibujar una palmera en las coordenadas p,q

@palm2At:

    print ink n4; paper n6;\
    at p,q;"OPQR";\
    at p+n1,q;"S TU";\
    at p+n1,q+n1; ink n0;"N";\
    at p+n2,q+n1;"M";\
    at p+n3,q+n1;"L";\
    at p+n4,q+n1;"V":\
    return

################################################
# Subrutina
# Dibujar nativo

@drawNative:

    # XXX TODO check: the char at 8,11 is code 96 (notation £ in BASin?)
    print ink n0;paper n6;\
    at n10,n8;" _ `";\
    at 11,n8;"}~.,";\
    at 12,n8;"{|\?":\
    return

################################################
# Subrutina
# Dibujar municiones

@drawAmmo:

    print ink n0;paper n6;\
    at 12,14; "hi":\
    return

################################################
# Subrutina
# Dibujar provisiones

@drawSupplies:

    gosub @graphicCharset2:\
    print at 12,14; ink n0; paper n6;"90  9099 0009":\
    gosub @graphicCharset1:\
    return

################################################
# Subrutina
# Dibujar serpiente

@drawSnake:

    gosub @graphicCharset2:\
    print ink n0;paper n6;\
    at 12,14; "xy":\
    gosub @graphicCharset1:\
    return

################################################
# Subrutina
# Dibujar doblones
# Entrada: dub=número de doblones

@drawDubloons:

    gosub @graphicCharset2:\
    print ink n0;paper n6;\
    at 12,12; "vw vw vw vw vw vw vw vw"(to dub*3):\
    gosub @graphicCharset1:\
    return

################################################
# Combate naval

@shipBattle:

    paper n1:cls:gosub @spanishCharset:
    print at 21,n10; ink n7; paper n2;" Munici";o$;"n = ";ammo
    for z=n0 to val "21": print at z,n0; ink n0; paper n6;"________ ": next z
    print at n2,n0; ink n0; paper n7;"1";at n9,n0;"2";at 16,n0;"3"
    gosub @graphicCharset1
    for z=n3 to val "17" STEP n7
    print at z,n6; ink n2; paper n6;"cde";at z+n1,n6;"fg";at z+n1,n1;"hi"
    gosub @graphicCharset2: print at z-n1,n4; ink n0; paper n6;"1";at z,n4;"2";at z+n1,n4;"3": gosub @graphicCharset1
    next z
    let m=n6: let n=val "20"
    for z=n1 to val "30": gosub @drawWave: next z

@fireCommand:

    gosub @moveShip
    if inkey$="1" then let o=n3: gosub @fire
    if inkey$="2" then let o=n10: gosub @fire
    if inkey$="3" then let o=val "17": gosub @fire
    goto @fireCommand

@fire:

    print at o-n1,n9; ink n6; paper n1;"+";at o+n1,n9;"-"
    gosub @moveShip: print at o-n1,n9; ink n6; paper n1;" ";at o+n1,n9;" "
    print at o,n9; ink n6; paper n1;" j": gosub @moveShip
    for z=n9 to val "30"
      print at o,z; ink n6; paper n1;" j"
        if m=o and z=n or m=o-n1 and z=n or m=o-n2 and z=n then goto @sunk
        if m=o and z=n+n1 or m=o-n1 and z=n+n1 or m=o-n2 and z=n+n1 then goto @sunk
    next z
    print at o,30; paper n1;"  "
    let ammo=ammo-n1
    gosub @spanishCharset: print at 21,22; ink n7; paper n2;ammo: gosub @graphicCharset1
    if ammo<=n0 then goto @theEnd
    return

@drawWave:

    print ink n5;\
    at int (rnd*20)+n1,int (rnd*20)+11;"kl":\
    return

@moveShip:

    let ship=int (rnd*n4)+n1
    let n=n+(ship=n1 and n<28)-(ship=n2 and n>18)
    let m=m+(ship=n3 and m<17)-(ship=n4 and m>n1)
    print at m,n; ink n7; paper n1;" ab ";at m+n1,n;" 90 ";at m+n2,n-n1;" 678 ";at m-n1,n;"   ";at m+n3,n;"   "
    if ship=n5 then gosub @drawWave
    return

################################################
# Subrutina
# Barco hundido

@sunk:

    print at m,n; ink n7; paper n1;"   ";at m+n1,n;" ab";at m+n2,n;" 90"
    print at m,n; ink n7; paper n1;"   ";at m+n1,n;"   ";at m+n2,n;" ab"
    print at m,n; ink n7; paper n1;"   ";at m+n1,n;"   ";at m+n2,n;"   "
    gosub @pause100
    if a(sPos)>=13 and a(sPos)<=16 then let sunk=sunk+n1: let score=score+val "1e3"
    if a(sPos)=13 then let a(sPos)=n10
    if a(sPos)=14 then let a(sPos)=n9
    if a(sPos)=15 then let a(sPos)=n8
    if a(sPos)=16 then let a(sPos)=n7
    let ammo=ammo-n1
    cls:goto @aboard

################################################
# Atacar barco

@attackShip:

# ¿No se puede hacer eso?:
    if a(sPos)<13 or a(sPos)=21 or a(sPos)=treasureIsland then goto @impossibleAttack
# ¿No queda munición?:
    if ammo<=n0 then goto @noAmmoLeft
# ¿Combate naval?:
    if a(sPos)>=13 and a(sPos)<=16 then goto @shipBattle

################################################
# Atacar un bote propio

    gosub @wipePanel

    gosub @spanishCharset
    print at 19,n3; ink n5; paper n0;"Disparar por error a uno de tus propios";at 20,n8;"botes..."
# Pausa:
    gosub @pause400

    if not int(rnd*2) then print at 20,n3;"Por suerte el disparo no ha dado en el blanco.":goto @L6694

    print at 20,n3;"La bala alcanza su objetivo. Esto desmoraliza a la tripulaci";o$;"n."
    let morale=morale-n2

# Herir a un número aleatorio de hombres:
    for z=n1 to int(rnd*n2)+n2:\
        gosub @manInjured:\
    next z

@L6694:

    gosub @pause400
    gosub @shipPanel:goto @shipCommand

################################################
# Subrutina
# Herir a un marinero

@manInjured:

    let injured=int (rnd*men)+n1:\
    if not s(injured) then goto @manInjured
    let s(injured)=s(injured)-n1:\
    goto @checkAlive

################################################
# No queda munición

@noAmmoLeft:

    gosub @wipePanel
    gosub @spanishCharset:\
    print at 17,13; ink n0; paper n4;"Informe":\
    print at 19,n2; ink n5; paper n0;"No te queda munici";o$;"n."
    gosub @pause300:\
    goto @theEnd

################################################
# Matar

@attack:

    if c(iPos)=n2 or c(iPos)=n4 or c(iPos)=n6 then \
        gosub @impossible:\
        gosub @islandPanel:\
        return

    gosub @wipePanel: gosub @spanishCharset
    print at 17,n1; ink n0; paper n4;"Atacas y matas"

    if c(iPos)=n5 then print at 19,n1; paper n0;"pero la serpiente mata a un hombre.": gosub @chooseDeadOne: goto @L6897
    if c(iPos)=n9 then print at 19,n1; paper n0;"pero un poblado entero es un";at 20,n1;"enemigo muy dif";i$;"cil. Tienes una baja.": gosub @chooseDeadOne: goto @L6898
    let kill=int (rnd*n5)+n1
    #let z=int (rnd*n2)+n2
    if kill>=n3 then \
        let dub=int(rnd*n2)+n2:print at 19,n1; paper n0;"Encuentras ";fn l$(dub);" ";fn d$(dub);" en el";at 20,n1;"cuerpo del nativo muerto.": let cash=cash+dub: goto @L6895
    if kill=n1 then \
        print at 19,n1; paper n0;"El nativo muere, pero";at 20,n1;"antes mata a uno de la tripulaci";o$;"n.": gosub @chooseDeadOne: goto @L6895
    if kill=n2 then \
        print at 19,n1; paper n0;"  El nativo tiene provisiones";at 20,n1;"escondidas en su taparrabos.": let supplies=supplies+n1

@L6895:

    gosub @graphicCharset2: for z=n10 to val "13": print at z,n8; paper n6; ink n0;"t   ": next z
    print at n9,n8; paper n6; ink n0;"u": print at n10,n9; paper n0; ink n7;"nop";at 11,n9;"qrs": gosub @graphicCharset1

@L6897:

    let c(iPos)=n4

@L6898:

    gosub @pause160
    gosub @islandPanel: gosub @checkTheEnd
    return

################################################
# Tormenta

@storm:

    gosub @wipePanel
    gosub @stormySky
    #gosub @spanishCharset: print ink n0; paper n1;bright n1;fn c$(panelTop,"TORMENTA")
    let damage=damage+int (rnd*40)+11:\
    if damage>100 then let damage=100
    print at 19,n1; paper n0;"Una tormenta causa destrozos en el barco.";at 20,n1;"El da";n$;"o total es del ";damage;" por ciento."
    gosub @graphicCharset1

# Efecto visual de lluvia:

    for z=n1 to val "70"
        print  ink n7; paper n5;\
        at n2,cloud0X;";;;;";\
        at n2,cloud1X;";;;":\
        pause n3
        print ink n7; paper n5;\
        at n2,cloud0X; "]]]]";\
        at n2,cloud1X;"]]]":\
        pause n3
        print ink n7; paper n5;\
        at n2,cloud0X; "[[[[";\
        at n2,cloud1X;"[[[":\
        pause n3
    next z
    print ink n7; paper n5;\
    at n2,cloud0X;"    ";\
    at n2,cloud1X;"   "

    gosub @checkTheEnd:\
    gosub @shipPanel:\
    return

################################################
# Dibujar el escenario

# Pendiente!!! Convertir en subrutina

@scenery:

# Comprobar final del juego (esto no debe ir aquí!!!):
    gosub @checkTheEnd
# Dibujar paisaje de mar y el barco:
    gosub @seaAndShip

# Dibujar los detalles de cada escenario:
    if a(sPos)=n2 then \
        gosub @drawBigIsland5:\
        gosub @palm1At0419:\
        goto @drawReefs
    if a(sPos)=n3 then \
        gosub @drawBigIsland4:\
        gosub @palm1At0414:\
        gosub @palm1At0419:\
        gosub @palm1At0424:\
        gosub @drawShark:\
        goto drawReefs
    if a(sPos)=n4 then \
        gosub @drawLittleIsland2:\
        gosub @palm1At0414:\
        goto drawReefs
    if a(sPos)=n5 then \
        gosub @drawLittleIsland1:\
        gosub @palm1At0424:\
        goto drawReefs
    if a(sPos)=n6 then \
        gosub @drawLittleIsland1:\
        gosub @palm1At0424:\
        goto drawReefs
    if a(sPos)=n6 then \
        gosub @drawLittleIsland2:\
        gosub @palm1At0414:\
        goto drawReefs
    if a(sPos)=n7 then \
        gosub @drawBigIsland3:\
        gosub @palm1At0419:\
        goto drawReefs
    if a(sPos)=n8 then \
        gosub @drawBigIsland2:\
        gosub @palm1At0414:\
        gosub @drawShark:\
        goto drawReefs
    if a(sPos)=n9 then \
        gosub @drawBigIsland1:\
        gosub @palm1At0424:\
        goto drawReefs
    if a(sPos)=n10 then \
        gosub @palm1At0424:\
        gosub @drawTwoLittleIslands:\
        goto drawReefs
    if a(sPos)=11 then \
        gosub @drawShark:\
        goto drawReefs
    if a(sPos)=13 then \
        gosub @palm1At0424:\
        gosub @drawTwoLittleIslands:\
        gosub @drawEnemyShip:\
        goto drawReefs
    if a(sPos)=14 then \
        gosub @drawBigIsland1:\
        gosub @palm1At0424:\
        gosub @drawEnemyShip:\
        goto drawReefs
    if a(sPos)=15 then \
        gosub @drawBigIsland2:\
        gosub @palm1At0414:\
        gosub @drawEnemyShip:\
        goto drawReefs
    if a(sPos)=16 then \
        gosub @drawBigIsland3:\
        gosub @palm1At0419:\
        gosub @drawEnemyShip:\
        goto drawReefs
    if a(sPos)=17 then \
        gosub @drawLittleIsland2:\
        gosub @palm1At0414:\
        gosub @drawBoat:\
        gosub @drawLittleIsland1:\
        gosub @palm1At0424:\
        goto drawReefs
    if a(sPos)=18 then \
        gosub @drawLittleIsland1:\
        gosub @palm1At0424:\
        gosub @drawBoat:\
        goto drawReefs
    if a(sPos)=19 then \
        gosub @drawBigIsland4:\
        gosub @palm1At0414:\
        gosub @palm1At0419:\
        gosub @palm1At0424:\
        gosub @drawBoat:\
        gosub @drawShark:\
        goto drawReefs
    if a(sPos)=20 then \
        gosub @drawBigIsland5:\
        gosub @palm1At0419:\
        gosub @drawBoat:\
        goto drawReefs
    if a(sPos)=21 then \
        gosub @drawShark

# Dibujar los posibles arrecifes:
@drawReefs:
    if a(sPos+15)=n1 then \
        gosub @drawFarIslands
    if a(sPos-15)=n1 then \
        gosub @bottomReef
    if a(sPos-n1)=n1 then \
        gosub @leftReef
    if a(sPos+n1)=n1 then \
        gosub @rightReef

    if a(sPos)=treasureIsland then \
        gosub @drawTreasureIsland

# Panel de comandos a bordo:
    gosub @shipPanel
    goto @shipCommand

################################################
# Subrutina
# Dibujar una palmera en las coordenadas 4,19

@palm1At0419:

    let gy=n4:let gx=19

################################################
# Subrutina
# Dibujar una palmera en las coordenadas gy,gx

@palm1At:

    print at gy,gx; ink n4; paper n1;"OPQR";at gy+n1,gx;"S TU";at gy+n1,gx+n1; ink n6; "N";at gy+n2,gx+n1;"M";at gy+n3,gx+n1;"L":\
    return

################################################
# Subrutina
# Dibujar una isla grande

@drawBigIsland5:

    print at n7,18; ink n4; paper n1;"HI A";at n8,17;"GBC";at n9,16;"FD";at n10,14;"JKE";at 11,13;"FC"
    return

################################################
# Subrutina
# Dibujar una palmera en las coordenadas 4,24:

@palm1At0424:

    let gy=n4:let gx=val"24":goto @palm1At

################################################
# Subrutina
# Dibujar una palmera en las coordenadas 4,14

@palm1At0414:

    let gy=n4:let gx=val"14":goto @palm1At

################################################
# Subrutina
# Dibujar una isla grande:

@drawBigIsland4:

    print at n7,16; ink n4; paper n1;"WXYA";at n8,14;":C FD";at n9,13;":BE";at n10,12;"FC":\
    return

################################################
# Subrutina
# Dibujar una isla pequeña:

@drawLittleIsland2:

    print at n8,14; ink n4; paper n1;":C";at n7,16;"A";at n9,13;":D";at n10,12;"FE":\
    return

################################################
# Subrutina
# Dibujar una isla pequeña:

@drawLittleIsland1:

    print at n8,23; ink n4; paper n1;"JKC";at n9,22;":D";at n10,21;"FE":\
    return

################################################
# Subrutina
# Dibujar una isla grande:

@drawBigIsland3:

    print at n7,21; ink n4; paper n1;"Z123";at n8,19;":C";at n9,18;":D";at n10,15;"FBE";at 11,13;"JKC":\
    return

################################################
# Subrutina
# Dibujar una isla grande

@drawBigIsland2:

    print at n7,17; ink n4; paper n1;"Z123";at n8,14;"FBC";at n9,13;"GD";at n10,12;"FE":\
    return

################################################
# Subrutina
# Dibujar una isla grande

@drawBigIsland1:

    print at n7,20; ink n4; paper n1;"HI A";at n8,19;"GBC";at n9,18;"FD";at n10,16;"JKE":\
    return

################################################
# Subrutina
# Dibujar dos islas pequeñas

@drawTwoLittleIslands:

    print at n6,17; ink n4; paper n1;"WXY  A";at n7,16;"A   A   FC";at n8,15;":© :© GD";at n9,14;"GD   FE";at n10,13;"FE":\
    return

################################################
# Subrutina
# Dibujar arrecifes en primer plano

@bottomReef:

    print at 14,n2; ink n0; paper n1;" A  HI   HI       HI  HI  A";at 15,n0;"WXY  :©     Z123     :©":\
    return

################################################
# Subrutina
# Dibujar horizonte de islas

@drawFarIslands:

    print at n2,n0; ink n4; paper n5;"Z123 HI A Z123 HI A Z123 HI Z123":\
    return

################################################
# Subrutina
# Dibujar arrecifes a la izquierda

@leftReef:

    print at 13,n0; ink n0; paper n1;"HI";at 11,n1;"A";at n4,n0;"A";at n8,n0;"WXY";at n6,n1;"HI":\
    return

################################################
# Subrutina
# Dibujar arrecifes a la derecha

@rightReef:

    print at n4,30; ink n0; paper n1;"HI";at n6,28;"A";at n7,29;"WXY";at n9,31;"A":\
    return

################################################
# Subrutina
# Dibujar barco enemigo

@drawEnemyShip:

    print ink n6; paper n1;\
    at n4,11;" ab";\
    at n5,11;" 90";\
    at n6,11;"678":\
    return

################################################
# Subrutina
# Dibujar el bote de desembarco

@drawBoat:

    print at n7,11; ink n6; paper n1;"<>":\
    return

################################################
# Subrutina
# Dibujar aleta de tiburón

@drawShark:

    print at 13,18; ink n7; paper n1;"S":return

################################################
# Subrutina
# Dibujar la isla del tesoro

@drawTreasureIsland:

    gosub @graphicCharset1: print at n7,16; ink n4; paper n1;"A A   HI";at n8,13;"FBBBC";at n9,12;"GD";at n10,n10;"JKE"
    print at 11,n9; ink n4; paper n1;":C";at 12,n8;"FD"
    print at 13,n8; ink n1; paper n4;" HI Z123  HI A  A A  A ";at 14,20;"BB"
    print at 13,31; ink n4; paper n1;"E"
    gosub @palm1At0419: gosub @palm1At0424: gosub @palm1At0414

# Cofre del tesoro:
    gosub @udg2:print at n9,22; ink n0; paper n4;"\A\B":gosub @udg1
# Quitar este rótulo!!! Anunciarlo en el panel:
    gosub @spanishCharset: print at 11,13; ink n7; paper n2;t$
    gosub @graphicCharset1

    return

################################################
# Subrutina
# Informe

@report:

    gosub @saveScreen:gosub @wipePanel:gosub @spanishCharset
    print ink n7; paper n0;at 4,n1'"Hombres:",alive'"D";i$;"as:",day'"Hundimientos:",sunk'"Da";n$;"os %:",damage'"Moral:",morale'"Provisiones:",supplies'"Doblones:",cash'"Munici";o$;"n:",ammo
    for z=n1 to val "600"
        if len inkey$ then goto @reportEnd
    next z

@reportEnd:

# Restaurar pantalla y regresar:
    goto @restoreScreen

################################################
# Subrutina
# Panel de comandos

# Nota!!! Esta rutina sustituye a las dos originales.

@shipPanel:
@islandPanel:
@panel:

    gosub @spanishCharset
    print ink n7;\
    print at 17,16;fn o$("Informe",1,1)
    print at 18,16;fn o$("Tripulaci"+o$+"n",1,1)

    let possibleDisembarking=b(sPos)=n1 or a(sPos)=treasureIsland
    print at 19,16;fn o$("Desembarcar",1,possibleDisembarking)
    let possibleEmbarking=not possibleDisembarking
    print at 19,16;fn o$("emBarcar",3,possibleEmbarking)

    let possibleAttacking=1
    print at 20,16;fn o$("Atacar",1,possibleAttacking)
    let possibleTrading=c(iPos)=n9
    print at 21,16;fn o$("Comerciar",1,possibleTrading)
    #goto @directionsMenu

################################################
# Subrutina
# Panel de comandos a bordo

# Obsoleto!!!

#@shipPanel

    #gosub @spanishCharset
    #print ink n7;\
    #at 17,16;fn v$("I")+"nforme";\
    #at 19,16;fn v$("T")+"ripulaci"+o$+"n";\
    #at 18,16;fn v$("D")+"esembarcar";\
    #at 20,16;fn v$("A")+"tacar barco"

################################################
# Subrutina
# Menú de direcciones

#@directionsMenu

    print paper n7; ink n0;\
    at panelTop,29; "N";\
    at panelBottom,29;"S";\
    at panelTop+n1,28;"O E":\
    plot 233,27: draw ink n0;n6,n0:\
    plot 236,24: draw ink n0;n0,n7:\
    return

################################################
# Selección de comando

# Nota!!! Este módulo sustituirá a los dos existentes.
# Pendiente!!!

@command:

################################################
# Subrutina
# Informe de tripulación

@crewReport:

    gosub @saveScreen:\
    gosub @wipePanel:\
    gosub @spanishCharset

    print ink n7;paper n2;\
    at n1,n10;"Tripulaci";o$;"n";\
    at n4,n1;"Nombre";\
    at n4,18;"Condici";o$;"n"

    for z=n1 to men:\
        print ink n5;\
        at z+n5,n1;fn n$(z);\
        at z+n5,18;fn u$(s$(s(z)+n1)):\
    next z

    gosub @graphicCharset1

    for z=n1 to val"700"
        if len inkey$ then goto @crewReportEnd
    next z

@crewReportEnd:

# Restaurar pantalla y regresar:
    goto @restoreScreen

################################################
# Encallar

@runAground:

    gosub @graphicCharset1:\
    gosub @wipeSea:\
    gosub @drawFarIslands:\
    gosub @bottomReef:\
    gosub @leftReef:\
    gosub @rightReef

    print at n8,14; ink n7;"ABC";at n9,14;"DEF";at n10,14;"GHI"
    print at n10,17; ink n0; paper n1;"WXY     A";at n6,19;"A   Z123";at 11,n6;"A   HI";at n4,n5;"Z123    HI";at n8,n7;"HI  A"
    gosub @wipePanel
    let damage=damage+int(rnd*20)+10:\
    if damage>100 then let damage=100
    gosub @spanishCharset:\
    print at 19,n5; ink n5; paper n0;x$;"Has encallado!";at 20,n8;damage;"% de da";n$;"os."
    if damage=100 then print at 20,n7; ink n5; paper n0;"TOTAL"
    print ink n0; paper n4;fn c$(17,"INFORME")
    gosub @manInjured
    gosub @chooseDeadOne
    let morale=morale-int (rnd*n4)+n1
    gosub @pause300
    if damage=100 then goto @theEnd
    gosub @shipPanel
    goto @scenery

################################################
# Subrutina
# Borrar panel de comandos

@wipePanel:

    load!"zp0i0b0l06"code fn a(panelTop-n1):return

################################################
# Subrutina
# Dibujar el barco con la proa elevada

@drawShipUp:

    print paper n1;ink n7;\
    at shipY,shipX;"ABC";\
    at shipY+n1,shipX;"DEF";\
    at shipY+n2,shipX;"GHI":\
    return

################################################
# Subrutina
# Dibujar el barco con la popa elevada

@drawShipDown:

    print paper n1;ink n7;\
    at shipY,shipX;"JKL";\
    at shipY+n1,shipX;"MNO";\
    at shipY+n2,shipX;"PQR":\
    return

################################################
# Subrutina
# Dibujar cielo de tormenta, las nubes y el sol

@stormySky:

    load!"zp5i5b0l03"code fn a(n0):\
    let noStorm=n0:\
    goto @finishTheSky

################################################
# Subrutina
# Dibujar mar y cielo

@seaAndSky:

    gosub @wipeSea

# Dibujar olas:
    gosub @graphicCharset1:\
    paper n1:ink n5
    for z=n1 to val"15":\
        print\
        at int (rnd*12)+n4,int (rnd*28)+n1;"kl";\
        at int (rnd*12)+n4,int (rnd*28)+n1;"mn":\
    next z

################################################
# Subrutina
# Dibujar cielo despejado, las nubes y el sol

@sunnySky:

    load!"zp5i5b1l03"code fn a(n0):let noStorm=n1

################################################
# Final de dos subrutinas (@sunnySky y @stormySky)
# Dibujar el cielo, las nubes y el sol:

@finishTheSky:

    gosub @graphicCharset2:\
    print paper n5;bright noStorm;\
    at n0,26; ink n6; "AB";\
    at n1,26;"CD"
    let cloud0X=int (rnd*n9)+n1:\
    let cloud1X=int (rnd*n9)+val"13"
    print ink n7; paper n5;bright noStorm;\
    at n0,cloud0X;"EFGH";\
    at n1,cloud0X;"IJKL";\
    at n0,cloud1X;"MNO";\
    at n1,cloud1X;"PQR"
    gosub @graphicCharset1:\
    return

################################################
# Subrutina
# Borrar mar

@wipeSea:

    load!"zp1i1b0l13"code fn a(n3):return

################################################
# Subrutina
# Dibujar compás sobre el mar

# Anulada!!!
    #gosub @spanishCharset
    #print at 11,29; ink n7;" N ";at 15,29;" S ";at 12,29;"   ";at 13,29;"O E";at 14,29;"   "
    #plot 243,78
    #draw n0,-20
    #plot 241,68
    #draw n4,n0
    #return

################################################
# Subrutina
# Preparación del juego

@init:

    load!"zp0i0b0l20"code fn a(n2)
    print ink n7; paper n0; flash n1;\
    fn c$(val "10","Espera a que prepare el barco...")
    randomize

    # El mapa consta de 135 casillas (9 filas de 15 columnas)
    let locations=val"135":\
    dim a(locations)

    let reef=n1
# Rodear el mapa con arrecifes:
# norte:
    for z=n1 to 16: let a(z)=reef: next z
# sur:
    for z=120 to locations: let a(z)=reef: next z
# este:
    for z=30 to 105 step 15: let a(z)=reef: next z
# oeste:
    for z=31 to 106 step 15: let a(z)=reef: next z

# Poner un tipo de isla al azar en cada casilla
# (códigos de 2 a 21):
    for z=17 to 119:\
        if a(z)<>reef then let a(z)=int (rnd*20)+n2
    next z

# La isla del tesoro es el tipo de isla 22:
    let treasureIsland=val"22"
# Elegir el lugar de la isla del tesoro:
    let a(int(rnd*11)+94)=treasureIsland

# Elegir la posición del barco en el mapa:
    let sPos=int (rnd*11)+32

# Nota!!! Aún no está clara la función de la matriz B().
# Parece que guarda un marcador para ciertos tipos de islas.
    dim b(locations)
    for z=17 to 119:\
        if a(z)<>reef and a(z)<>11 and a(z)<>12 and a(z)<>21 then let b(z)=n1
    next

# Coordenadas del gráfico del barco:
    let shipY=n9:let shipX=n4
# Líneas superior e inferior del panel:
    let panelTop=val"17":let panelBottom=val"21"

# Nombres de los miembros de la tripulación:
    restore @menNamesData:\
    let lenght=n0
    for z=n1 to men:\
        read z$:if len z$>lenght then let lenght=len z$
    next z
    dim d$(men,lenght)

# Pendiente!!! Hacer que los diez tripulantes sean elegidos
# al azar de entre muchos más nombres, y cada vez en
# diferente orden.
# Inacabado!!!

    for z=n1 to men
@retryMan:
        restore #menNamesData
        read z$:if not len z$ then goto @retryMan
        let d$(z)=chr$(len z$+1)+z$
    next z

# Inacabado!!!
@menNamesData:

    data "Jacobo Gorri"+o$+"n"
    data "Guille 'El Chico'"
    data "Quique Morgano"
    data "Edu 'El Ingl"+e$+"s'"
    data "Juan Plata 'El largo'"
    data "Bartolom"+e$+" Robertos"

    data "Julen Terrador"
    data "Jer"+o$+"nimo el Tuerto"
    data "Ricardo Borriquero"
    data "Benito Pistola"
    data "Barbanegra"
    data "Pedro Pistolas"
    data "Felipe Llejo"
    data "Vicente Rador"
    data "Caracortada"
    data "Pedro Medario"
    data ""

# Grados de estado físico de los miembros de la tripulación:

    dim s$(n5,13)
    restore @menStatusData
    for z=n1 to n5: read s$(z): next z

@menStatusData:

    data "muerto","herido grave","herido leve","magullado","en forma"

# Indicadores de estado físico de la tripulación (0-4):
    dim s(men)
    for z=n1 to men: let s(z)=n4: next z

# Constantes de códigos usados en el mapa de las islas:
    # Faltan códigos!!!
    let coast=n1
    let dubloonsFound=n2
    let nativeFights=n3
    let snake=n5
    let nativeSupplies=n7
    let nativeAmmo=n8
    let nativeVillage=n9

# Pistas:
    let path=int (rnd*n4)+n1
    let tree=int (rnd*n4)+n1
    let village=int (rnd*n10)+n1
    let ect=int (rnd*n2)+n1
    let dir=int (rnd*n4)+n1
    let pace=int (rnd*n9)+n1

# Nombres de los poblados:
    restore @villageNamesData
    dim f$(n10,n9)
    for z=n1 to n10:\
        read f$(z):\
    next z

# Los nombres de poblados
# son palabras compuestas en esperanto,
# de significado gracioso:
# Incompleto!!!

@villageNamesData:

    data "Mislongo","Ombreto","Figokesto","Miseduka","Topikega","Fibaloto","!!!Manplata","!!!Figarbaro","Ursorelo","Kukumo"

# Puntos cardinales para las pistas:
    dim g$(n4,n5)
    let g$(n1)="norte": let g$(n2)="sur": let g$(n3)="este": let g$(n4)="oeste"

# Izquierda y derecha para las pistas:
    dim h$(n2,n9)
    let h$(n1)="izquierda": let h$(n2)="derecha"

# Variables de la trama:
    let men=n10:\
    let sunk=n0:\
    let cash=n5:\
    let morale=n10:\
    let alive=men:\
    let ammo=n2:\
    let supplies=n10:\
    let damage=n0:\
    let score=n0:\
    let trade=n0:\
    let day=n0:\
    let find=n0

    return

################################################
# Subrutina
# Comprobar las condiciones del final del juego

@checkTheEnd:

    gosub @checkAlive
    if morale<=n0 then goto @theEnd
    if damage>=100 then goto @theEnd
    if supplies<=n0 then goto @theEnd
    #if cash<n0 then goto @theEnd
    return

################################################
# Subrutina
# Comprobar si todos miembros de la tripulación han muerto

@checkAlive:

    let alive=men
    for z=n1 to men:let alive=alive-not s(z):next z
    if not alive then goto @theEnd
    return

################################################
# Subrutina
# Crear mapa de la isla

@islandMap:

    dim c(30)
    restore @islandData
    for z=n1 to 18:read w:let c(w)=n1:next z

    for z=n8 to 23:\
        if c(z)<>n1 then let c(z)=int (rnd*n5)+n2
    next z

    let c(int (rnd*n4)+20)=nativeVillage:\
    let c(int (rnd*n4)+14)=nativeAmmo:\
    let c(int (rnd*n4)+n8)=nativeSupplies
    # Posición inicial en la isla:
    let iPos=int (rnd*n4)+n8

    return

@islandData:

    data n1,n2,n3,n4,n5,n6,n7,12,13,18,19,24,25,26,27,28,29,30

################################################
# Subrutina
# Panel de comandos en tierra

# Obsoleto!!!

#@islandPanel

    #gosub @spanishCharset: gosub @directionsMenu
    #print ink n7;\
    #at 17,16;fn v$("C")+"omerciar";\
    #at 19,16;fn v$("I")+"nforme";\
    #at 18,16;fn v$("M")+"atar";\
    #at 20,16;"em"+fn v$("B")+"arcar"
    #return

################################################
# Subrutina
# Elegir un miembro de la tripulación para que muera

@chooseDeadOne:

    for z=n1 to men
        if s(z) then let s(z)=n0: return
    next z
    goto @checkAlive

################################################
# Desembarcar en la isla del tesoro

@enterTreasureIsland:

    gosub @pause20
    # Pistas acertadas:
    let find=n0

    cls : gosub @sunnySky
    gosub @wipeIsland
    gosub @graphicCharset2:\
    print ink n4; paper n6;\
    at n3,n0; " 5     6       45     6       5"
    for z=n0 to 24 STEP n8:\
        print ink n0; paper n6;\
        at n3,z+n3;":©";\
        at n4,z+n2;":©";\
        at n5,z+n1;":©";\
        at n6,z;":©":\
    next z
    gosub @spanishCharset:\
    print at n7,n0; ink n7; paper n2;"   1       2       3       4    "
    # cambiar esto por un fichero de atributos!!!
    for z=n8 to 21:\
        print at z,n0; ink n7; paper n0;l$:\
    next z
    gosub @graphicCharset1:\
    print at 17,n1; ink n5; paper n0;"xy                         pq   vs                         rs   wu                         tu"
    plot 25,44:draw 20,n10:draw n0,30:draw n2,n2:draw 100,n0:draw n2,-n2:draw n0,-60:draw -n2,-n2:draw -100,n0:draw -n2,n2:draw n0,19:draw -20,n0
    plot 220,44:draw -15,n5:draw n0,20:draw -n2,n2:draw -30,n0:draw -n2,-n2:draw n0,-40:draw n2,-n2:draw 30,n0:draw n2,n2:draw n0,14:draw 15,n0
    gosub @spanishCharset:\
    print at 14,n7; paper n0;q$;"Qu";e$;" camino";at 16,n8;c$;"?";at 15,23; flash n1;"?"
    gosub @getOption: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=path then let find=find+n1
    gosub @spanishCharset: print at 14,n7; paper n0;q$;"Qu";e$;" ";a$;"rbol";at 16,n8;c$;"?";at 15,23;"? "
    gosub @wipeIsland: print at n7,n0; ink n0; paper n6;" 1       2       3       4": gosub @graphicCharset1: for z=n2 to 26 STEP n8: let p=n3: let q=z: gosub @palm2At: next z
    gosub @getOption: gosub @spanishCharset: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=tree then let find=find+n1
    print at 14,n7; paper n0;"Izquierda Derecha";at 16,n8;"I=1  D=2 ";at 15,23;"? "
    gosub @getOption: gosub @spanishCharset: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=ect then let find=find+n1
    gosub @wipeIsland: for z=n3 to n7: print at z,n1; ink n0; paper n6;z-n2;"  ";f$(z-n2): next z
    for z=n3 to n7: print at z,12; ink n0; paper n6;z+n3;"  ";f$(z+n3): next z
    print at n7,12; ink n0; paper n6;"0  ";f$(n10)
    gosub @graphicCharset2: print at n5,27; ink n4; paper n6;"ST";at n6,27;"VUW"
    gosub @spanishCharset: print at 14,n7; paper n0;" Poblado  ";at 13,n7;q$;"Cu";a$;"l";at 16,n8;" ";c$;".";at 15,23;"? "
    gosub @getOption: gosub @spanishCharset: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=village then let find=find+n1
    print at 13,n7; paper n0;q$;"Qu";e$;" camino";at 14,n7;c$;"?";at 16,n7;"1N 2S 3E 4O";at 15,23;"? "
    gosub @getOption: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=dir then let find=find+n1
    print at 13,n7; paper n0;q$;"Cu";a$;"ntos";at 14,n7;"pasos,";at 16,n7;c$;"?";at 15,23;"? "
    gosub @getOption: print at 15,23; paper n0;option: beep .2,30
    gosub @pause100: if option=pace then let find=find+n1
    if find=n6 then \
        print at 13,n7; paper n0;x$;"Hemos encontrado ";at 14,n7;"el oro, ";at 16,n7;c$;"!": goto @treasureFound
    if find<n6 then \
        print at 13,n7; paper n0;x$;"Nos hemos";at 14,n7;" equivocado ";at 16,n7;c$;"!"
    gosub @pause100
    goto @theEnd

################################################
# Subrutina
# Obtener un dígito pulsado
# Salida: variable 'option' con el número del dígito (0-9)

@getOption:

    pause n0:let option=code inkey$-code"0"
    if option<n1 or option>n9 then beep .1,n10: goto @getOption
    return

################################################
# Subrutinas
# Pausas

@pause600:

    let wait=val"600":goto @pause

@pause400:

    let wait=val"400":goto @pause

@pause300:

    let wait=val"300":goto @pause

@pause200:

    let wait=val"200":goto @pause

@pause160:

    let wait=val"160":goto @pause

@pause100:

    let wait=val"100":goto @pause

@pause20:

    let wait=val"20"

@pause:
    for z=n1 to wait:next z:return

################################################
# Subrutina
# Borrar la tierra

@wipeIsland:

    load!"zp6i6b0l05"code fn a(n3):return

################################################
# Subrutina
# Seleccionar el juego de caracteres de la ROM

@romCharset:

    poke val"23606",not pi:\
    poke val"23607",val"60":\
    return

################################################
# Subrutina
# Hacer residente el juego de caracteres 1
# (que contiene gráficos)

@graphicCharset1:

    load!"jr3"code charset
# Provisional!!! Para poder alternar cómodamente con el juego en ROM durante la depuración:
    goto @ramCharset

################################################
# Subrutina
# Hacer residente el juego de caracteres 2
# (que contiene gráficos)

@graphicCharset2:

    load!"jr4"code charset
# Provisional!!! Para poder alternar cómodamente con el juego en ROM durante la depuración:
    goto @ramCharset

################################################
# Subrutina
# Hacer residante el juego de caracteres 3
# (copia del estándar pero castellanizado)

@spanishCharset:

    load!"esRomChr" code charset
# Provisional!!! Para poder alternar cómodamente con el juego en ROM durante la depuración:
# ...sigue en @ramCharset y retorna.

################################################
# Subrutina
# Seleccionar el juego de caracteres residente

@ramCharset:

    randomize charset-val"256":poke val"23606",peek val"23670":poke val"23607",peek val"23671":randomize:return

################################################
# Subrutina
# Seleccionar grupo de GDU principal

@udg1:

    load!"jr6" code usr "a":return

################################################
# Subrutina
# Seleccionar grupo de GDU secundario

# Este conjunto de GDU solo contiene el gráfico del cofre
# del tesoro en las posiciones «A» y «B», porque en ZX
# Spectrum 128 los GDU «T» y «U» (que era su posición
# original en el grupo de GDU principal) no son accesibles.

@udg2:

    load!"bnUDG1" code usr "a":return

################################################
# Fin del juego

@theEnd:

    gosub @pause20

# Quitar esta cortinilla!!!:
    for z=n0 to 21: print at z,n0; paper n6; ink n0;l$: beep .001,z+n9: next z
    gosub @graphicCharset1: for z=n1 to 15 STEP n7: let p=z: let q=27: gosub @palm2At: let q=n1: gosub @palm2At: next z

    gosub @spanishCharset:\
    print ink n7; paper n2;fn c$(n3,"FIN DEL JUEGO")
    if supplies<=n0 then \
        let p$="Las provisiones se han agotado.":\
        gosub @tell
    if morale<=n0 then \
        let p$="La tripulaci"+o$+"n se ha amotinado.":\
        gosub @tell
    if ammo<=n0 then \
        let p$="La munici"+o$+"n se ha terminado.":\
        gosub @tell
    if not alive then \
        let p$="Toda tu tripulaci"+o$+"n ha muerto.":\
        gosub @tell
    if damage=100 then \
        let p$="El barco est"+a$+" muy da"+n$+"ado y es imposible repararlo.":\
        gosub @tell
    if find=n6 then \
        let p$="Lo lograste, "+c$+".":\
        gosub @tell
    if cash<=n0 then \
        let p$="No te queda dinero.":\
        gosub @tell

    print at 21,n0; paper n2;"Pulsa una tecla para ver tus puntos"
    pause n0:beep .2,30
    for z=n0 to 20:\
        print at z,n5; paper n6;"                      ":\
    next z

    print at 21,n0; paper n2;"Pulsa cualquier tecla para jugar";at n0,13;"Puntuaci"+o$+"n"

    print at n2,n10; paper n4; ink n7;"Barcos hundidos";at n5,n6;"Negocios con ";e$;"xito";at n8,n6;"Direcciones correctas";at 11,n6;"D";i$;"as que has sobrevivido";at 14,n6;"Puntos por el tesoro";at 17,n10; flash n1;"Puntuaci";o$;"n total"
    print at n4,13; ink n0; paper n6;"x 1000  puntos";at n7,13;"x 200   puntos";at n10,13;"x 1000  puntos";at 13,13;"x 200   puntos";at 16,16;"puntos"
    print at n4,n8; paper n6; ink n0;sunk;at n7,n8;trade;at n10,n8;find;at 13,n8;day
    let score=score+(find*val"1e3")
    let score=score+(day*val"200")
    if find=n6 then print at 16,11; paper n6; ink n0;"4000": let score=score+val"4e3": goto @theEnd01
    print at 16,11; paper n6; ink n0;"0"

@theEnd01:

    print at 19,12; paper n6; ink n0;score;" puntos"
    for z=n1 to 50: next z
    pause n0
    goto @start

################################################
# Subrutina
# Introducción al juego

@intro:

    border n0: paper n0: ink n7: bright n0: flash n0:cls

    #gosub @skullBorder

    gosub @spanishCharset
    let p$="Eres el "+c$+" del barco pirata "+b$+". Un viejo marinero te ha contado que existe una isla llamada "+t$+", que esconde un fabuloso tesoro. Pero por desgracia nadie sabe d"+o$+"nde est"+a$+" exactamente y hay muchas islas en esa zona.":gosub @tel
lCR
    let p$="Los nativos de las islas vecinas conocen pistas para llegar al tesoro. Deber"+a$+"s comerciar con ellos para que te las digan.":gosub @tellCR
    let p$="Cuando encuentres la isla "+t$+", sigue las pistas. Pero ten cuidado...":gosub @tellCR

    print fn c$(val "20","Pulsa cualquier tecla"):pause val"6e3"

    return

################################################
# Subrutina
# Imprimir borde de calaveras de decoración:

@skullBorder:

    gosub @graphicCharset2
    let gc=n2:gosub @skullLine:\
    let gc=n1

################################################
# Subrutina
# Imprimir línea de calaveras en canal gc

@skullLine:

    print#gc;at n0,n0;paper n0;ink n7;bright n1;\
    "  nop  nop  nop  nop  nop  nop  "'\
    "  qrs  qrs  qrs  qrs  qrs  qrs  ":\
    return

################################################
# Hallazgo del tesoro

@treasureFound:

    gosub @pause100
    load!"zp5i5b1l03"code fn a(n0):\
    load!"zp6i6b0l18"code fn a(n4)
    gosub @sunnySky
    for z=n7 to 22 STEP n5:\
        let p=n5: let q=z: gosub @palm2At:\
    next z
    let p=n7: let q=n3: gosub @palm2At
    let p=n7: let q=26: gosub @palm2At
# Cofre del tesoro:
    gosub @udg2:\
    print at 13,n8; ink n0; paper n6;\
    "pq          xy                  rs          vs                  tu      "\
    +"\A\B"+"    wu":\
    gosub @udg1
    let p=11: let q=28: gosub @palm2At
    let p=11: let q=n0: gosub @palm2At
    gosub @graphicCharset2: print at 17,13; ink n1; paper n6;"lm"
    gosub @spanishCharset
    print at 21,n0; ink n7; paper n2;x$+"Capit"+a$+"n, somos ricos!"
    gosub @pause200
    goto @theEnd

################################################
# Subrutina
# Imprimir párrafo formateado en la posición actual
# Entrada: texto en p$

@tell:

    if len p$<=cpl then goto @tellEnd

    for z=cpl to n1 step -n1
        if p$(z)=" " then \
            print p$(to z-n1):\
            let p$=p$(z+n1 to):\
            goto @tell
    next z

@tellEnd:

    print p$:\
    return

################################################
# Subrutina
# Imprimir párrafo formateado, con separación posterior
# Entrada: texto en p$

@tellCR:

    gosub @tell:print:return

################################################
# Subrutina
# Imprimir párrafo formateado en bocadillo de nativo
# Entrada: texto en p$

@nativeTell:

    let tw=cpl:let ty=n6:let tx=16:let tw=10

################################################
# Subrutina
# Imprimir párrafo formateado en una zona
# Entrada:
#   p$=text
#   tw=anchura máxima
#   ty=línea superior
#   tx=columna izquierda

@tellZone:

    if len p$<=tw then goto @tellZoneEnd

    for z=tw to n1 step -n1
        if p$(z)=" " then \
            print at ty,tx;p$(to z-n1):\
            let p$=p$(z+n1 to):\
            let ty=ty+n1:\
            goto @tellZone
    next z

@tellZoneEnd:

    print at ty,tx;p$:\
    return

################################################
# Demo de caracteres (para depuración)

@showCharsets:

    cls
    gosub @spanishCharset: print '"UDG 1":gosub @udg1:gosub @showUdg
    gosub @spanishCharset: print '"UDG 1":gosub @udg2:gosub @showUdg

    gosub @romCharset: print '"Tipo 1 (en @graphicCharset1)": gosub @graphicCharset1: gosub @ramCharset:gosub @showASCII

    gosub @romCharset: print '"Tipo 2 (en @graphicCharset2)": gosub @graphicCharset2:gosub @ramCharset:gosub @showASCII

    gosub @romCharset: print '"Tipo 3 (en @spanishCharset)":gosub @spanishCharset: gosub @ramCharset:gosub @showASCII

    gosub @romCharset:stop

@showASCII:

    for z=n32 to val"127": print chr$ z;: next z: return

@showUdg:

    for z=val"144" to val"164": print chr$ z;: next z:return

################################################
# Subrutina
# Salvar la pantalla

@saveScreen:

    erase!"tmpScreen":save!"tmpScreen"screen$:return

################################################
# Subrutina
# Restaurar la pantalla

@restoreScreen:

    load!"tmpScreen"screen$:return

################################################
# Probar gráficos (para depuración)

# Juego de caracteres con gráficos:
    gosub @graphicCharset1:gosub @ramCharset
# Imprimir gráfico:
    gosub 7310:rem graphic
# Restaurar juego de caracteres en ROM:
    gosub @romCharset
    stop

################################################
# Grabación en DISCiPLE o +D con Beta DOS

save over d*"bn2" line val"11"


Páginas relacionadas

Historial de desarrollo del proyecto abandonado Bandera negra en Sinclair BASIC
Historial de desarrollo del proyecto abandonado de juego de simulación Bandera negra en Sinclair BASIC.
Bandera negra [para SAM Coupé, en MBim]
Juego de simulación y aventuras para SAM Coupé, escrito en MasterBASIC con formato MBim.
La isla del Coco
Juego de simulación y aventura.
Black Flag
Nueva version del juego de ZX Spectrum Jolly Roger, escrita en Forth, para ZX Spectrum 128.