Mario de Lama
malar@arrakis.es
http://www.arrakis.es/~malar
En system hay varias formas de conseguir que algo se ejecute mientras estás presionando una tecla, hasta hay implementadas dos rutinas: REPEATER (#40E88) y REPEATERCH (#51735). Ambas precisan de dos argumentos:
2: código de la tecla a repetir
1: secundario u objeto que deseamos que se evalúe repetidamente
Por ejemplo:
::
ZERO 1LAMBIND
WaitForKey 2DROP
REPEATER
SEVENTEEN
:: $ "REPETICION " 1GETLAM #1+DUP 1PUTLAM #>$ &$ DISPROW4 ;
ABND
;
¿Qué diferencia hay entre REPEATER y REPEATERCH? Podéis verla si estudiáis el código asociado a cada una de estas etiquetas o compilando el ejemplo anterior
(también bajandoos el ejemplo compilado con REPEATER o con REPEATERCH)
El código SEVENTEEN corresponde al cursor ABAJO que es al que debéis dar tras presionar en la variable en la que guardéis los programas.
Por si no tenéis JAZZ a mano os doy el código de ambos comandos:
REPEATER ( dirección #40E88 )
::
'R'R DUP EVAL
OVER REPKEY? NOTcase2DROP
VERYSLOW
BEGIN
2DUPSWAP REPKEY?
WHILE
:: EVAL SLOW ;
REPEAT
3DROP
;
REPEATCH ( dirección #51735 )
::
'R'R DUP EVAL
OVER REPKEY? NOTcase2DROP
BEGIN
2DUPSWAP REPKEY?
WHILE
::
::
PTR 4DCC6
EVAL
;
;
REPEAT
3DROP
;
REPEATER es más lento, incluso pone un VERYSLOW al principio para que el primer paso sea aún más lento.
Pero esta forma de repetir tecla tiene un gran inconveniente: En los niveles 1 y 2 tenemos siempre el código de la tecla a repetir y un secundario, por ello es bastante complicado usar la pila para hacer operaciones y demás. Prácticamente estamos restringidos a programar rutinas que no alteren la pila.
Para obviar este problema, podemos hacer el siguiente bucle:
BEGIN
.... ( Código a repetir mientras mantengamos presionada la tecla X)
NúmeroDeCódigoDeLaTeclaX REPKEY?
NOT_UNTIL
Un ejemplo de esta forma de repetir la pulsación de una tecla lo tenemos a continuación. En él se toma como argumento un gráfico y se presenta en la pila pudiendo desplazarlo hacia arriba y abajo en saltos de 6 pixeles o hacia derecha e izquierda a saltos de 4 pixeles según mantengamos pulsado alguno de los cursores. Estos incrementos son muy convenientes si el gráfico es el de un texto con la fuente pequeña ya que podemos pasar de línea en línea en vertical o de carácter en carácter en horizontal.
El código de VG está listo para ser compilado con JAZZ y, como veis, tiene definidos previamente cada uno de los códigos de las teclas a usar para dar una mayor legibilidad al ejemplo:
VG ( CHEKSUM #C0Fh, 320 by )
DEFINE kpNoShift ONE
DEFINE kcUpArrow ELEVEN
DEFINE kcDownArrow SEVENTEEN
DEFINE kcLeftArrow SIXTEEN
DEFINE kcRightArrow EIGHTEEN
DEFINE kcOn FORTYFIVE
::
CK1&Dispatch
TWELVE
::
DUPGROBDIM FALSE {{ Y X TEST }}
ClrDA1IsStat RECLAIMDISP TURNMENUOFF
ZEROZERO ROT XYGROBDISP
BEGIN
WaitForKey
::
kpNoShift #=casedrop
::
kcUpArrow #=casedrop
::
BEGIN
WINDOWCORNER SWAPDUP SIX #>ITE
DROPZERO #6- SWAP WINDOWXY
kcUpArrow REPKEY?
NOT_UNTIL
;
kcDownArrow #=casedrop
::
BINT40h Y #> ?SEMI
BEGIN
WINDOWCORNER SWAP #6+ Y OVER #-
BINT40h #>?SKIP
:: DROP Y BINT40h #- ;
SWAP WINDOWXY
kcDownArrow REPKEY?
NOT_UNTIL
;
kcLeftArrow #=casedrop
::
BEGIN
WINDOWCORNER DUP #4 #<ITE
DROPZERO #4- WINDOWXY
kcLeftArrow REPKEY?
NOT_UNTIL
;
kcRightArrow #=casedrop
::
BINT_131d X #> ?SEMI
BEGIN
WINDOWCORNER #4+ X OVER #-
BINT_131d #>?SKIP
:: DROP X BINT_131d #- ;
WINDOWXY
kcRightArrow REPKEY?
NOT_UNTIL
;
kcOn #=casedrop :: TRUE TEST! ;
DROP DoBadKey
;
2DROP DoBadKey
;
TEST
UNTIL
ABND TURNMENUON RECLAIMDISP ClrDAsOK
;
;
La base de este algoritmo es REPKEY? ( #KeyCode -> TRUE/FALSE ) que devuelve TRUE si la tecla #KeyCode está presionándose. Naturalmente también puede hacerse un programa más simple en este caso:
VG2 ( CHEKSUM #E749h, 145 by )
DEFINE kpNoShift ONE
DEFINE kcUpArrow ELEVEN
DEFINE kcDownArrow SEVENTEEN
DEFINE kcLeftArrow SIXTEEN
DEFINE kcRightArrow EIGHTEEN
DEFINE kcOn FORTYFIVE
::
CK1&Dispatch
TWELVE
::
FALSE {{ TEST }}
ClrDA1IsStat RECLAIMDISP TURNMENUOFF
ZEROZERO ROT XYGROBDISP
BEGIN
WaitForKey
::
kpNoShift #=casedrop
::
kcUpArrow #=casedrop :: SCROLLUP ;
kcDownArrow #=casedrop :: SCROLLDOWN ;
kcLeftArrow #=casedrop :: SCROLLLEFT ;
kcRightArrow #=casedrop :: SCROLLRIGHT ;
kcOn #=casedrop :: TRUE TEST! ;
DROP DoBadKey
;
2DROP DoBadKey
;
TEST
UNTIL
ABND TURNMENUON RECLAIMDISP ClrDAsOK
;
;
Ya que los comandos SCROLL tienen incorporados REPEATER en su código. A pesar de ser más corto VG2 que VG si compiláis y ejecutáis ambos programas veréis las ventajas de VG: Mayor rapidez y flexibilidad ya que se puede variar fácilmente el incremento X e Y.
Espero que os sirva de algo.