===SPRGES - Parte Basic ===
SprGes es un grupo de programas que tenía por objeto acabar con el límite de memoria que Qbasic imponía a las matrices de gráficos. A través de un programa residente en memoria (TSR) vinculado a un controlador de interrupción se reservaba memoria para gráficos de modo MCGA (320x200, 256 colores, el mejor modo gráfico para juegos usando gráficos VGA estándar).
El programa estaba creado en una mezcla de [[csembler_y_programas_relacionados|CSEMBL] (para la parte del TSR) y basic (para el juego en cuestión).
Una versión compilada (funciona solo en sistemas anteriores a XP, que soporten archivos .COM, y podría ser peligroso ejecutarla en Windows) puede descargarse de [[http://jgmoyay.apagada.com]].
Antes de ejecutar estos programas es necesario haber cargado SPRGES16.COM o SPRGES2.COM
* Juego16.BAS: un prototipo de juego.
DECLARE SUB LUCHA (X%, Y%)
DECLARE SUB Centrar (Lin%, MSG$)
DECLARE FUNCTION ValorM% (X%, Y%)
DECLARE SUB SPRITEPSET2 (N%)
DECLARE SUB CARGASPRITES ()
DECLARE SUB PonerM (X%, Y%, Objeto%)
DECLARE SUB MostrarP (X%, Y%)
DECLARE FUNCTION VALORMAPA% (X%, Y%)
DEFINT A-Z
PRINT "JUEGOMAP."
PRINT "Ejemplo de juego, creado con MAPAGES2, que utiliza SPRGEST."
SLEEP 5: I$ = INKEY$: I$ = ""
CLS
DIM SHARED NULL AS STRING * 1: NULL = CHR$(0)
'Este programa utiliza SPRGEST para poner gr ficos en pantalla.
'Lo que sigue son matrices est ticas
'$STATIC
DIM SHARED RUTINAMAQUINA%(1 TO 16), MAQDESP%, MAQSEG%
'Inicializar la rutina secundaria de c¢digo m quina.
MAQDESP% = VARPTR(RUTINAMAQUINA%(1))
MAQSEG% = VARSEG(RUTINAMAQUINA%(1))
DEF SEG = MAQSEG%
RESTORE RutiMaqData
FOR F = 0 TO 15
READ DATO$
POKE MAQDESP% + F, VAL("&h" + LTRIM$(DATO$))
NEXT
DEF SEG
DIM SHARED MAPADESP%, MAPASEG%
'Tomar ubicaci¢n de INT 60h
DEF SEG = 0
I60 = 4 * &H60
des = PEEK(I60) + 256 * PEEK(I60 + 1)
MAPASEG% = PEEK(I60 + 2) + 256 * PEEK(I60 + 3)
DEF SEG = MAPASEG%
FOR F = 1 TO 8
IF PEEK(des + F + 1) <> ASC(MID$("SPR_GEST", F, 1)) THEN
PRINT "ERROR: SPRGEST (gestor de sprites y memoria) no cargado."
SYSTEM
END IF
NEXT
UBI = des + 10
MAPADESP% = PEEK(UBI) + 256 * PEEK(UBI + 1)
'No podr‚ utilizar los 256 sprites, puesto que ocupan mucho m s de
'64Kb.
'$STATIC
DIM SHARED SPRITES%(32766), SPRDESP%, SPRSEG%
'DIM SHARED SPRIT%(FRE(1) / 2)
SPRDESP% = VARPTR(SPRITES%(0))
SPRSEG% = VARSEG(SPRITES%(0))
SCREEN 13
CARGASPRITES
X = 0: Y = 0
SPRACT% = 0
LSTSPRACT% = -1
Armapa$ = "JUEGO"
IF Armapa$ > "" THEN
IF INSTR(Armapa$, ".") = 0 THEN Armapa$ = Armapa$ + "._MA"
DEF SEG = MAPASEG%
BLOAD Armapa$, MAPADESP%
DEF SEG
END IF
'Poner el marcador de energ¡a
Energia = 200
LINE (256, 0)-(319, 199), 0, BF
LINE (280, 0)-(296, 200 - Energia), 7, B
LINE (280, 200 - Energia)-(296, 199), 7, BF
X0 = 1: Y0 = 1: ' ObjetoSPR = ValorM(X1 + X0 + 1, Y1 + Y0 + 1)
DO
ObjetoSPR = ValorM(X1 + X0 + 1, Y1 + Y0 + 1)
SELECT CASE ObjetoSPR
CASE 1
Oro = Oro + 100: ObjetoSPR = 0': PLAY "L63CDEFCDEG"
'SOUND 1000, .5: SOUND 2000, .5
FOR W = 1 TO 5: SOUND 500 * W, .1: NEXT
CASE 20, 21
PLAY "L63A#C"
SWAP ObjetoSPR, ObjetCogido
SELECT CASE ObjetCogido
CASE 20: Nobjeto$ = "Hacha"
CASE 21: Nobjeto$ = "Espada"
END SELECT
END SELECT
PonerM X1 + X0 + 1, Y1 + Y0 + 1, 50 + DIRE + ESTA
LOCATE 25, 1: PRINT USING "ORO: ##### Arma:\ \ Llaves:####"; Oro; Nobjeto$; llaves;
ESTA = ESTA + 1: IF ESTA > 1 THEN ESTA = 0
DO
GOSUB MueveMalos
IN$ = INKEY$
LOOP UNTIL IN$ > ""
PonerM X1 + X0 + 1, Y1 + Y0 + 1, ObjetoSPR
SELECT CASE IN$
CASE "4", NULL + "K"
X0 = X0 - 1
DIRE = 2
IF X0 < 0 THEN
X0 = 0: IF X1 > 0 THEN X1 = X1 - 1
END IF
VM1 = ValorM(X1 + X0 + 1, Y1 + 1 + Y0)
IF VM1 > 1 AND VM1 < 20 THEN X0 = X0 + 1
IF VM1 >= 30 AND VM1 <= 36 THEN X0 = X0 + 1: LUCHA X1 + X0, Y1 + Y0 + 1
CASE "8", NULL + "H"
Y0 = Y0 - 1
DIRE = 4
IF Y0 < 0 THEN
Y0 = 0: IF Y1 > 0 THEN Y1 = Y1 - 1
END IF
VM1 = ValorM(X1 + X0 + 1, Y1 + 1 + Y0)
IF VM1 > 1 AND VM1 < 20 THEN Y0 = Y0 + 1
IF VM1 >= 30 AND VM1 <= 36 THEN Y0 = Y0 + 1: LUCHA X1 + X0 + 1, Y1 + Y0
CASE "6", NULL + "M"
X0 = X0 + 1
DIRE = 0
IF X0 > 7 THEN
X0 = 7: IF X1 < 119 THEN X1 = X1 + 1
END IF
VM1 = ValorM(X1 + X0 + 1, Y1 + 1 + Y0)
IF VM1 > 1 AND VM1 < 20 THEN X0 = X0 - 1
IF VM1 >= 30 AND VM1 <= 36 THEN X0 = X0 - 1: LUCHA X1 + X0 + 2, Y1 + Y0 + 1
CASE "2", NULL + "P"
Y0 = Y0 + 1
DIRE = 6
IF Y0 > 5 THEN
Y0 = 5: IF Y1 < 248 THEN Y1 = Y1 + 1
END IF
VM1 = ValorM(X1 + X0 + 1, Y1 + 1 + Y0)
IF VM1 > 1 AND VM1 < 20 THEN Y0 = Y0 - 1
IF VM1 >= 30 AND VM1 <= 36 THEN Y0 = Y0 - 1: LUCHA X1 + X0 + 1, Y1 + Y0 + 2
CASE CHR$(27): EXIT DO
END SELECT
LOOP
RutiMaqData:
'Rutina en c¢digo m quina
DATA b8,00,00,bb,00,00,b9,00,00,ba,00,00,cd,60,cb,90
MueveMalos:
ESTADO = ESTADO + 1
IF ESTADO > 20 THEN
FOR F = 0 TO 8: FOR G = 0 TO 6
XF = X1 + F: YG = Y1 + G 'Espero que esto acelere el programa.
VM = ValorM(XF, YG)
SELECT CASE VM
CASE 30, 31, 33, 34: PonerM XF, YG, VM + 1
CASE 32, 35: PonerM XF, YG, VM - 2
END SELECT
NEXT: NEXT
MostrarP X1, Y1
ESTADO = 0
END IF
RETURN
SUB CARGASPRITES
Archiv$ = "Juego"
Archiv$ = LTRIM$(RTRIM$(Archiv$))
PRINT "Cargando la paleta.": PRINT "Espere, por favor..."
FOR F = 0 TO 7: FOR G = 0 TO 31
LINE (G * 8, 64 + F * 8)-(7 + G * 8, 73 + F * 8), F * 32 + G, BF
NEXT: NEXT
DIM RGB AS STRING * 3
NFILE = FREEFILE
OPEN Archiv$ + "._PA" FOR BINARY AS NFILE
FOR F = 0 TO 255
GET NFILE, , RGB
PALETTE F, CVL(RGB + NULL)
NEXT F
CLOSE NFILE
PRINT "Cargando los dibujos.": PRINT "Espere, por favor..."
NFILE = FREEFILE
OPEN Archiv$ + "._SP" FOR BINARY AS NFILE
LIMITF = UBOUND(SPRITES%)
'X = 0: Y = 0
F = 0
DO UNTIL EOF(1)
GET NFILE, , SPRITES%(F)
'MK$ = MKI$(SPRITES%(F))
'SPRITES%(F) = CVI(RIGHT$(MK$, 1) + LEFT$(MK$, 1))
IF F = LIMITF THEN EXIT DO
F = F + 1
LOOP
CLOSE NFILE
END SUB
SUB Centrar (Lin, MSG$)
X2 = 40 - LEN(MSG$) / 2
IF X2 = 0 THEN LOCATE Lin, 1 ELSE LOCATE Lin, X2
PRINT MSG$
END SUB
SUB LUCHA (X, Y)
SHARED Energia, ObjetCogido
Venem = ValorM(X, Y)
SELECT CASE Venem
CASE 30 TO 32 'Anillo
Ataque2 = 1: Efecto = 15
'Soborno = 500: ObjetDesea = 0: Enigma = -1
CASE 33 TO 35 'Devorador
Ataque2 = 2: Efecto = 10
'Soborno = 500: ObjetDesea = 0: Enigma = 0
END SELECT
IF Ataque2 = 0 THEN EXIT SUB
SOUND 250, .4: SOUND 100, .8: SOUND 250, .4
SELECT CASE ObjetCogido
CASE 20 'Hacha
Ataque1 = 1
CASE 21 'Espada
Ataque1 = 2
END SELECT
Suerte1 = INT(RND * Ataque1 * 10): Suerte2 = INT(RND * Ataque2 * 10)
IF Suerte1 > Suerte2 THEN
PonerM X, Y, 0
ELSE
'Si han tenido el mismo resultado, ambos pierden
IF Suerte1 = Suerte2 THEN PonerM X, Y, 0
'Si el malo ha tenido mucha suerte, el bueno pierde m s vida.
IF Suerte2 > Suerte1 * 10 THEN Efecto = Efecto * 2
Energia = Energia - Efecto
LINE (256, 0)-(319, 199), 0, BF
LINE (280, 0)-(296, 200 - Energia), 7, B
LINE (280, 200 - Energia)-(296, 199), 7, BF
IF Energia < 0 THEN
Centrar 12, "Est s Muerto"
END
END IF
END IF
END SUB
SUB MostrarP (X, Y)
DEF SEG = MAQSEG%
'FOR F = 0 TO 16: PRINT RIGHT$("0" + HEX$(PEEK(MAQDESP% + F)), 2); " "; : NEXT: PRINT
POKE MAQDESP% + 1, Y: POKE MAQDESP% + 2, 0
POKE MAQDESP% + 4, X: POKE MAQDESP% + 5, 0
POKE MAQDESP% + 7, SPRSEG% MOD 256
POKE MAQDESP% + 8, INT(SPRSEG% / 256)
POKE MAQDESP% + 10, SPRDESP% MOD 256
POKE MAQDESP% + 11, INT(SPRDESP% / 256)
'FOR F = 0 TO 16: PRINT RIGHT$("0" + HEX$(PEEK(MAQDESP% + F)), 2); " "; : NEXT: PRINT
'END
CALL ABSOLUTE(MAQDESP%)
DEF SEG
END SUB
SUB PonerM (X, Y, Objeto)
DEF SEG = MAPASEG%
IF X > 127 OR Y > 255 THEN BEEP: EXIT SUB
MEMUBIC& = MAPADESP% + (X * 256& + Y)
POKE MEMUBIC&, Objeto
DEF SEG
END SUB
SUB SPRITEPSET2 (N%)
DIM SPR%(514)
N2% = N% * 512
GET (0, 0)-(31, 31), SPR%(0)
FOR F = 0 TO 511
SPR%(F + 2) = SPRITES%(N2% + F)
NEXT
'SPR%(0) = 32: SPR%(1) = 32
PUT (288, 0), SPR%(0), PSET
END SUB
FUNCTION ValorM (X, Y)
DEF SEG = MAPASEG%
IF X > 127 OR Y > 255 THEN BEEP: EXIT FUNCTION
MEMUBIC& = MAPADESP% + (X * 256& + Y)
ValorM = PEEK(MEMUBIC&)
DEF SEG
END FUNCTION
FUNCTION VALORMAPA% (X, Y)
DEF SEG = MAPASEG%
MEMUBIC% = MAPADESP% + (Y * 256 + X)
VALORMAPA% = PEEK(MEMUBIC%)
DEF SEG
END FUNCTION
* Mapages: un prototipo de editor de mapa
DECLARE SUB ReorgaMapa ()
DECLARE SUB SPRITEPSET2 (n%)
DECLARE SUB CARGASPRITES ()
DECLARE SUB PONERM (X%, Y%, Objeto%)
DECLARE SUB MOSTRARP (X%, Y%)
DECLARE FUNCTION VALORMAPA% (X%, Y%)
DEFINT A-Z
PRINT "MAPAGEST."
PRINT "Creador de mapas para juegos que utilizan SPRGEST."
SLEEP 5: I$ = INKEY$: I$ = ""
CLS
DIM SHARED NULL AS STRING * 1: NULL = CHR$(0)
'Este programa utiliza SPRGEST para poner gr ficos en pantalla.
'Lo que sigue son matrices est ticas
'$STATIC
DIM SHARED RUTINAMAQUINA%(1 TO 16), MAQDESP%, MAQSEG%
'Inicializar la rutina secundaria de c¢digo m quina.
MAQDESP% = VARPTR(RUTINAMAQUINA%(1))
MAQSEG% = VARSEG(RUTINAMAQUINA%(1))
DEF SEG = MAQSEG%
RESTORE RutiMaqData
FOR F = 0 TO 15
READ DATO$
POKE MAQDESP% + F, VAL("&h" + LTRIM$(DATO$))
NEXT
DEF SEG
DIM SHARED MAPADESP%, MAPASEG%
'Tomar ubicaci¢n de INT 60h
DEF SEG = 0
I60 = 4 * &H60
des = PEEK(I60) + 256 * PEEK(I60 + 1)
MAPASEG% = PEEK(I60 + 2) + 256 * PEEK(I60 + 3)
DEF SEG = MAPASEG%
FOR F = 1 TO 8
IF PEEK(des + F + 1) <> ASC(MID$("SPR_GEST", F, 1)) THEN
PRINT "ERROR: SPRGEST (gestor de sprites y memoria) no cargado."
SYSTEM
END IF
NEXT
UBI = des + 10
MAPADESP% = PEEK(UBI) + 256 * PEEK(UBI + 1)
'No podr‚ utilizar los 256 sprites, puesto que ocupan mucho m s de
'64Kb.
'$STATIC
DIM SHARED SPRITES%(32766), SPRDESP%, SPRSEG%
'DIM SHARED SPRIT%(FRE(1) / 2)
SPRDESP% = VARPTR(SPRITES%(0))
SPRSEG% = VARSEG(SPRITES%(0))
SCREEN 13
FOR F = 0 TO 10 STEP 2
FOR G = 0 TO 10 STEP 2
PONERM F, G, 0
PONERM F + 1, G, 1
PONERM F, G + 1, 1
PONERM F + 1, G + 1, 0
NEXT
NEXT
PONERM 0, 1, 1
PONERM 1, 0, 1
CARGASPRITES
X = 0: Y = 0
SPRACT% = 0
LSTSPRACT% = -1
DO
IF SPRACT% <> LSTSPRACT% THEN
SPRITEPSET2 (SPRACT%)
END IF
LSTSPRACT% = SPRACT%
MOSTRARP X1, Y1
LINE (X0 * 32, Y0 * 32)-(X0 * 32 + 31, Y0 * 32 + 31), 7, B
LINE (X0 * 32 + 1, Y0 * 32 + 1)-(X0 * 32 + 30, Y0 * 32 + 30), 0, B
DO: IN$ = INKEY$: LOOP UNTIL IN$ > ""
SELECT CASE IN$
CASE NULL + CHR$(68)
INPUT "Grabar: Entre el nombre del archivo mapa:"; Armapa$
IF Armapa$ > "" THEN
IF INSTR(Armapa$, ".") = 0 THEN Armapa$ = Armapa$ + "._MA"
DEF SEG = MAPASEG%
BSAVE Armapa$, MAPADESP%, 32768!
DEF SEG
END IF
CASE NULL + CHR$(67)
INPUT "Cargar: Entre el nombre del archivo mapa:"; Armapa$
IF Armapa$ > "" THEN
IF INSTR(Armapa$, ".") = 0 THEN Armapa$ = Armapa$ + "._MA"
DEF SEG = MAPASEG%
BLOAD Armapa$, MAPADESP%
DEF SEG
END IF
'Cambiado 256 a 61 (en realidad s¢lo hay 63 dibujos (o menos))
CASE "+": SPRACT% = SPRACT% + 1: IF SPRACT% > 62 THEN SPRACT% = 0
CASE "*": SPRACT% = SPRACT% + 1: IF SPRACT% > 62 THEN SPRACT% = 62 - SPRACT%
CASE "-": SPRACT% = SPRACT% - 1: IF SPRACT% < 0 THEN SPRACT% = 61
CASE "/": SPRACT% = SPRACT% - 10: IF SPRACT% < 0 THEN SPRACT% = 62 + SPRACT%
CASE "4", NULL + "K"
X0 = X0 - 1
IF X0 < 0 THEN
X0 = 0: IF X1 > 0 THEN X1 = X1 - 1
END IF
CASE "8", NULL + "H"
Y0 = Y0 - 1
IF Y0 < 0 THEN
Y0 = 0: IF Y1 > 0 THEN Y1 = Y1 - 1
END IF
CASE "6", NULL + "M"
X0 = X0 + 1
IF X0 > 7 THEN
X0 = 7: IF X1 < 119 THEN X1 = X1 + 1
END IF
CASE "2", NULL + "P"
Y0 = Y0 + 1
IF Y0 > 5 THEN
Y0 = 5: IF Y1 < 248 THEN Y1 = Y1 + 1
END IF
CASE CHR$(13)
PONERM X0 + X1 + 1, Y0 + Y1 + 1, SPRACT%
'PLAY "C63"
MOSTRARP X1, Y1
CASE CHR$(27): EXIT DO
CASE NULL + CHR$(59)'F2
ReorgaMapa
MOSTRARP X1, Y1
CASE CHR$(10) 'CTR_RET
VM = VALORMAPA%(X1 + X0 + 1, Y1 + Y0 + 1)
IF VM >= 0 AND VM <= 62 THEN SPRACT% = VM
END SELECT
IF INSTR("24568", IN$) > 0 THEN PONERM X0 + X1 + 1, Y0 + Y1 + 1, SPRACT%
LOOP
RutiMaqData:
'Rutina en c¢digo m quina
DATA b8,00,00,bb,00,00,b9,00,00,ba,00,00,cd,60,cb,90
DatoJCarJuego:
'Datos de las paredes de varias direcciones del juego "JUEGO".
DATA 12,3,2,18,17,16,15,14,7,6,5,4,8,11,10,9:
SUB CARGASPRITES
DO
INPUT "Entre el nombre del juego de sprites:"; Archiv$
IF INSTR(Archiv$, ".") > 0 THEN
PRINT "Lo siento, no puede especificar una extensi¢n."
ELSE
EXIT DO
END IF
LOOP
Archiv$ = LTRIM$(RTRIM$(Archiv$))
PRINT "Cargando la paleta; espere, por favor..."
DIM RGB AS STRING * 3
NFILE = FREEFILE
OPEN Archiv$ + "._PA" FOR BINARY AS NFILE
FOR F = 0 TO 255
GET NFILE, , RGB
PALETTE F, CVL(RGB + NULL)
NEXT F
CLOSE NFILE
PRINT "Cargando los dibujos; espere, por favor..."
NFILE = FREEFILE
OPEN Archiv$ + "._SP" FOR BINARY AS NFILE
LIMITF = UBOUND(SPRITES%)
'X = 0: Y = 0
F = 0
DO UNTIL EOF(1)
GET NFILE, , SPRITES%(F)
'MK$ = MKI$(SPRITES%(F))
'SPRITES%(F) = CVI(RIGHT$(MK$, 1) + LEFT$(MK$, 1))
IF F = LIMITF THEN EXIT DO
F = F + 1
LOOP
CLOSE NFILE
END SUB
SUB MOSTRARP (X, Y)
DEF SEG = MAQSEG%
'FOR F = 0 TO 16: PRINT RIGHT$("0" + HEX$(PEEK(MAQDESP% + F)), 2); " "; : NEXT: PRINT
POKE MAQDESP% + 1, Y: POKE MAQDESP% + 2, 0
POKE MAQDESP% + 4, X: POKE MAQDESP% + 5, 0
POKE MAQDESP% + 7, SPRSEG% MOD 256
POKE MAQDESP% + 8, INT(SPRSEG% / 256)
POKE MAQDESP% + 10, SPRDESP% MOD 256
POKE MAQDESP% + 11, INT(SPRDESP% / 256)
'FOR F = 0 TO 16: PRINT RIGHT$("0" + HEX$(PEEK(MAQDESP% + F)), 2); " "; : NEXT: PRINT
'END
CALL ABSOLUTE(MAQDESP%)
DEF SEG
END SUB
SUB PONERM (X, Y, Objeto)
DEF SEG = MAPASEG%
IF X > 127 OR Y > 255 THEN BEEP: EXIT SUB
MEMUBIC& = MAPADESP% + (X * 256& + Y)
POKE MEMUBIC&, Objeto
DEF SEG
END SUB
SUB ReorgaMapa
CLS
PRINT " Petici¢n de reorganizaci¢n del mapa."
PRINT
PRINT " ATENCIàN: si su mapa no utiliza un jue-"
PRINT " go de objetos compatible con ®JUEGO¯, "
PRINT " esta opci¢n podr¡a arruinar su trabajo."
PRINT
INPUT "¨Proseguir?"; A$
IF A$ <> "S" AND A$ <> "s" THEN EXIT SUB
RESTORE DatoJCarJuego
FOR F = 0 TO 15
READ CADV
CAD$ = CAD$ + CHR$(CADV)
NEXT
FOR FX = 0 TO 127
FOR FY = 0 TO 255
VMACT = VALORMAPA(FX, FY)
'Utilizo IF...THEN IF ... THEN IF... THEN porque suele ser
'm s r pido que AND.
'1)- S¢lo se act£a sobre bloques de pared est ndar (2...18 excepto 13)
IF VMACT >= 2 THEN
IF VMACT <= 18 THEN
IF VMACT <> 13 THEN
VBL = 0
IF FX > 0 THEN VMIZQ = VALORMAPA(FX - 1, FY) ELSE VMIZQ = 0
IF FX < 127 THEN VMDCH = VALORMAPA(FX + 1, FY) ELSE VMDCH = 0
IF FY > 0 THEN VMARR = VALORMAPA(FX, FY - 1) ELSE VMARR = 0
IF FY < 255 THEN VMABA = VALORMAPA(FX, FY + 1) ELSE VMABA = 0
IF VMIZQ >= 2 THEN IF VMIZQ <= 18 THEN IF VMIZQ <> 13 THEN VBL = VBL + 1
IF VMDCH >= 2 THEN IF VMDCH <= 18 THEN IF VMDCH <> 13 THEN VBL = VBL + 2
IF VMARR >= 2 THEN IF VMARR <= 18 THEN IF VMARR <> 13 THEN VBL = VBL + 4
IF VMABA >= 2 THEN IF VMABA <= 18 THEN IF VMABA <> 13 THEN VBL = VBL + 8
PONERM FX, FY, ASC(MID$(CAD$, 1 + VBL, 1))
END IF
END IF
END IF
NEXT
LOCATE 15, 1: PRINT USING "###.## % del mapa completado."; (FX / 127) * 100
NEXT
END SUB
SUB SPRITEPSET2 (n%)
DIM SPR%(514)
N2% = n% * 512
GET (0, 0)-(31, 31), SPR%(0)
FOR F = 0 TO 511
SPR%(F + 2) = SPRITES%(N2% + F)
NEXT
'SPR%(0) = 32: SPR%(1) = 32
PUT (288, 0), SPR%(0), PSET
END SUB
FUNCTION VALORMAPA% (X, Y)
DEF SEG = MAPASEG%
IF X < 0 OR Y < 0 THEN BEEP: EXIT FUNCTION
IF X > 127 OR Y > 255 THEN BEEP: EXIT FUNCTION
MEMUBIC& = MAPADESP% + (X * 256& + Y)
VALORMAPA% = PEEK(MEMUBIC&)
DEF SEG
END FUNCTION