Llamada a un subrutina dentro de otra con un "on strig gosub"

Por Jury MSX

Expert (99)

imagem de Jury MSX

09-11-2021, 20:04

Hola a todos.
Tengo un problema con una subrutina en Basic donde se sale de ella cuando se aprieta al espacio.
El cuerpo principal llama a una rutina (nº1000) que tiene la función de dibujar una barra creciente-decreciente que se para con el espacio, según donde se pare, una variable N tendrá un valor mayor o menor que sirve para mover al sprite del protas en el cuerpo principal.
Esta rutina contiene un ON STRIG GOSUB para que detecte el espacio y salir de la rutina, pero durante la ejecución de esta rutina debo mover otro sprite por lo que hago otra llamada a otra rutina (nº 5000).
Si no hago la llamada a la rutina nº5000 todo va bien, pero si hago la llamada la barra espaciadora no detiene el bucle en muchas ocasiones y a veces el programa ni responde ya más al espacio y no sale de la rutina 1000.
Entiendo que la rutina 5000 queda dentro de la interrupción de salida por el espacio pero parece que anula la interrupción. Incluso si dentro de la rutina 5000 coloco otro ON STRIG GOSUB no me acaba de funcionar bien.

¿Alguien sabe como se podría plantear mejor para que funcione?

Ufff... espero que se me entienda!!!!!

Saludos y gracias.

Juan carlos

...
120 F=22:gosub 1000: AN=0.2+(n*0.080) ----- LLAMADA A LA SUBRUTINA 1000 
...
180 PUT SPRITE 0,(X,Y),1,W1:PUT SPRITE 1,(X,Y),15,W3
190 GOSUB 5000
...
1000 ON STRIG GOSUB 1160 :STRIG(0) ON:n=0   -------- RUTINA DONDE SE SALE CON LA BARRA ESPACIADORA
1010 S=BASE(10)+(32*F)+11
1015 FOR R=S TO (S+3)
1017 VPOKE R,11
1018 NEXT R
1020 FOR r=s TO (s+3)
1030 FOR t=12 TO15
1040 VPOKE r,t
1045 GOSUB 5000
1050 n=n+1 
1060 NEXT T
1070 NEXT R 
1080 FOR r=(s+3) TO s STEP(-1)
1090 FOR t=14 TO 11 STEP(-1)
1110 VPOKE r,t
1115 GOSUB 5000
1120 n=n-1
1130 next T
1140 next R
1150 goto 1020 
1160 STRIG(0) OFF:return 1170 
1170 return


5000 IF XB>LD THEN XP=4    --------------   RUTINA PARA MOVER UN SPRITE
5110 IF XB<LI then xp="-4" if ls then yp="4" if yb>LB THEN YP=-4
5140 XB=XB+XP
5150 YB=YB+YP
5160 SWAP W5,W6
5170 PUT SPRITE 2,(XB,YB),1,W5
5810 RETURN
Entrar ou registrar-se para comentar

Por theNestruo

Champion (351)

imagem de theNestruo

11-11-2021, 17:22

Creo que el problema que tienes es que cuando ocurre la interrupción del ON STRING puedes estar dentro de una subrutina o dentro de dos... y entonces los RETURN te hacen cosas raras.

Quizá lo más sencillo es declarar una variable E=0 (E de EXIT) en 1000, hacer que tu rutina de interrupción la ponga a 1 y nada más (1160 E=0:STRIG(0)OFF:RETURN) y mirar esa variable en 1150 IF E THEN RETURN ELSE 1020. De esta manera no necesitas "manipular" el flujo de ejecución y te vale a futuro, por si el día de mañana dicho flujo es más complejo.
De todos modos, estoy asumiendo que de 1010-1150 es "un frame"; esto es: que si pulso espacio no hará más veces ese bucle, pero que no hay necesidad de parar en medio de dicho bucle y acabará la iteración actual...
Si no es así, puedes probar a cambiar tus GOSUB 5000 por STRIG(0) STOP:GOSUB 5000:STRIG(0) ON para evitar que te salte mientras se está ejecutando la subrutina 5000... y lo que tienes, a priori, debería funcionar.

Por Jury MSX

Expert (99)

imagem de Jury MSX

12-11-2021, 12:40

Hola,
Gracias por la idea, la variable de salida funciona a la perfección!!! tenía un lío con los returns, según donde se para el bucle retornaba al programa principal o volvía a la rutina 5000.

Saludos.