martes, 22 de diciembre de 2015

Ejemplo de cursor en pantalla

He aquí un ejemplo de como podemos implementar un cursor en pantalla. 

Está pensado para trabajar, como un cursor en pantalla de modo texto, al uso de lo que estamos acostumbrados. 

Para realizar el cursor, tenemos que tener en cuenta tanto las características del BASIC como las limitaciones en pantalla a la hora de imprimir texto. 

Es decir, tenemos que gestionar dos cosas:

1) El texto que se encuentra en las coordenadas del cursor.

2) Los atributos de dicho texto (color del texto, color de fondo, brillo e intermitencia). 

El cursor debe desplazarse por la pantalla sin modificar el valor original de la celda donde se encuentre. Para ellos tenemos que tener en cuenta los puntos 1 y 2 cuando movamos dicho cursor. 

Para esto usaremos dos funciones del BASIC; 

1) SCREEN$ para obtener el carácter que está en las coordenadas X,Y.

2) ATTR para obtener sus atributos (color, fondo brillo e intermitencia). Usa el mismo mecanismo de coordenadas X e Y. 

La función SCREEN$ nos devuelve (solo) el carácter que está en la celda X,Y. No devuelve ni sus atributos (que se obtienen con ATTR) ni valor cuando el carácter en la celda es un UDG

Para obtener un valor si es un UDG hay una manera, que se describe en otro ejemplo

El valor que nos devuelve ATTR es un valor numérico que se descompone de la siguiente manera:
  • Si el valor es superior a 128, el carácter está en modo intermitente (FLASH 1).
  • Si el valor es superior a 68, el carácter tiene brillo (BRIGHT 1). 
  • El valor de ATTR (si toca restar porque es mayor de 68 y/o 128) dividido entre 8 nos da el color del fondo (PAPER). 
  • El valor de ATTR menos el valor del fondo (PAPER) nos da el color del carácter (INK). 

Extracto del programa de ejemplo: 
LET f=0
IF z>128 THEN LET f=1: LET z=z-128
LET b=0
IF z>64 THEN LET b=1: LET z=z-64
LET p=INT (z/8)
LET co=z-(p*8)
PRINT FLASH f; INK co; BRIGHT b; PAPER p;z$

La filosofía del cursor es sencilla:

1) Guardamos en dos variables el valor de la celda y sus astributos.

2) Imprimimos el cursor encima (OVER 1) ,intermitente (FLASH 1) y con brillo (BRIGHT 1) para que se vea fácil en el ejemplo.

3) Al movernos, restauramos el valor de la celda donde estábamos.

Llenamos la pantalla de caracteres generados de forma aleatoria y vemos como funciona el cursor. En la parte de abajo nos da una linea de ayuda con las teclas para mover dicho cursor.

He usado unos UDG de flechas en la linea de ayuda, para hacerlo más amigable.

El código BASIC lo puedes descargar de aquí.

Una versión del ejemplo pasada a código máquina la tienes aquí.

Debajo de la imagen está el listado completo por si lo quieres copiar y pegar.



















5 CLEAR
10 LET t$="Ejemplo de cursor"
20 CLS
30 BORDER 4
40 GO SUB 460
50 PRINT AT 0,INT ((32-LEN t$)/2); INK 2;t$
60 FOR y=1 TO 20
70 FOR x=0 TO 31
80 LET co=INT (RND*8)
90 IF co=2 THEN GO TO 80
100 LET ff=INT (RND*10)
110 LET f=0
120 IF ff>8 THEN LET f=1
130 LET p=INT (RND*8)
140 IF p=2 THEN GO TO 130
150 PRINT AT y,x; INK co; FLASH f; PAPER p;CHR$ (65+(1+(RND*60)))
160 NEXT x
170 NEXT y
180 LET x=0: LET y=1: LET xant=x: LET yant=y: LET z$= SCREEN$ (y,x): LET z=ATTR (y,x): PRINT AT y,x; OVER 1; FLASH 1; INK 2; BRIGHT 1;"\::"
190 PRINT AT 21,0; INK 0;"u(";CHR$ 144;"),d(";CHR$ 145;"),l(";CHR$ 146;"),r(";CHR$ 147;") o q"
200 LET i$=INKEY$
210 IF i$="q" THEN GO TO 420
220 IF i$<>"l" AND i$<>"r" AND i$<>"u" AND i$<>"d" THEN GO TO 200
230 LET xant=x: LET yant=y
240 IF i$="l" THEN IF x>=1 THEN LET x=x-1
250 IF i$="r" THEN IF x<31 THEN LET x=x+1
260 IF i$="u" THEN IF y>1 THEN LET y=y-1
270 IF i$="d" THEN IF y<20 THEN LET y=y+1
280 GO SUB 300
290 GO TO 200
300 LET f=0
310 IF z>128 THEN LET f=1: LET z=z-128
320 LET b=0
330 IF z>64 THEN LET b=1: LET z=z-64
340 LET p=INT (z/8)
350 LET co=z-(p*8)
360 PRINT AT yant,xant; OVER 0; FLASH f; INK co; BRIGHT b; PAPER p;z$
370 LET z$= SCREEN$ (y,x)
380 LET z=ATTR (y,x)
390 PRINT AT y,x; OVER 1; FLASH 1; INK 2; BRIGHT 1;"\::"
400 PRINT AT 0,26;"     ": PRINT AT 0,26;y;" ";x
410 RETURN
420 CLS : CLEAR : BORDER 7: PRINT AT 0,0; INK 0;"Adios"
430 STOP
440 DATA 0,24,60,126,126,24,24,0,0,24,24,126,126,60,24,0
450 DATA 0,16,48,126,126,48,16,0,0,8,12,126,126,12,8,0
460 RESTORE 440
470 FOR i=0 TO 15
480 READ a
490 IF i<=7 THEN POKE USR "a"+i,a
500 IF i>7 THEN POKE USR "b"+(i-8),a
510 NEXT i
520 RESTORE 450
530 FOR i=0 TO 15
540 READ a
550 IF i<=7 THEN POKE USR "c"+i,a
560 IF i>7 THEN POKE USR "d"+(i-8),a
570 NEXT i
580 RETURN



No hay comentarios: