Página 1 de 1

Rótulos demasiado lentos

Publicado: Jue Sep 03, 2020 7:59 pm
por zup
Aburrido, he pensado en inundar el CSSCGC de este año con minijuegos cutres. El problema es que las primeras rutinas me han salido demasiado cutres.

Para hacer mis juegos me he autoimpuesto las siguientes restricciones:
- Voy a usar el ZX Spin para programarlos.
- Van a ser 100% BASIC, sin rutinas en c/m.
- Los juegos deben parecer "de aficionados", sin optimizaciones más allá de lo evidente.
- Mucha, mucha reutilización de código.

Así que una de las primeras rutinas a programar eran rótulos gigantes. Parte del "encanto" de los juegos es que sean lentos, pero me parece que esta rutina tiene mucho hueco para optimizarse.

El listado es el siguiente:

Código: Seleccionar todo

1 LET score=23: GO SUB 9998: GO SUB 9950
8999 GO TO 9999
9700 REM PLOT PRINT
9720 LET x1=x: FOR i=1 TO LEN s$: IF s$(i)=" " THEN GO TO 9840
9730 LET y1=192-17-y: LET dir=8*(CODE s$(i))+PEEK 23606+256*PEEK 23607
9740 FOR j=0 TO 7: LET byte=PEEK dir
9750 FOR k=7 TO 0 STEP -1: LET bit=2^k
9760 FOR l=1 TO ph: FOR m=1 TO pw
9780 IF byte>=bit THEN PLOT x1+8*pw-k*pw+m,y1-j*ph-l
9810 NEXT m: NEXT l: IF byte>=bit THEN LET byte=byte-bit
9820 NEXT k
9830 LET dir=dir+1: NEXT j
9840 LET x1=x1+8*pw: NEXT i
9850 RETURN 
9950 REM GAME OVER
9951 BORDER 2: PAPER 2: INK 7: CLS 
9952 LET s$="GAME OVER": LET pw=2: LET ph=3: LET y=50: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9953 LET s$="Score: ": FOR i=1 TO 5-LEN STR$ score: LET s$=s$+" ": NEXT i
9954 LET s$=s$+STR$ score
9955 LET pw=2: LET ph=2: LET y=100: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9956 RETURN 
9970 GO TO 9700
9998 POKE 23672,0: POKE 23673,0: POKE 23674,0: RETURN 
9999 LET time=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET horas=INT (time/180000): LET time=time-horas*180000: LET minutos=INT (time/3000): LET time=time-minutos*3000: LET segundos=INT (time/50): LET time=time-segundos*50: PRINT AT 10,0;horas;"h:";minutos;"m:";segundos;"s.";time
La rutina (GOSUB 9700) acepta los siguientes parámetros:
  • x,y: coordenadas del texto, donde y es la parte superior de la pantalla
  • ph,pw: altura y anchura de cada pixel de los caracteres, ph=2 y pw=3 significarían caracteres el doble de alto y el triple de ancho
  • s$: cadena a imprimir
Según el reloj del spectrum (líneas 9998 y 9999), el castigo por fallar es una pantalla de Game Over que tarda 4 minutos y medio en dibujarse.

¿Es realmente TAN lento PLOT o la parte lenta son las matemáticas? El programa está subido en mediafire

Re: Rótulos demasiado lentos

Publicado: Jue Sep 03, 2020 9:53 pm
por K.O.D.
Ahora me lo descargaré para darle un vistazo. Recuerdo que en la MH, en la sección Trucos publicaron tropecientas pequeñas rutinas de rótulos, una buena parte eran solo BASIC (y lentas como el caballo del malo), igual por ahí encuentras algo interesante...

Re: Rótulos demasiado lentos

Publicado: Vie Sep 04, 2020 9:06 am
por zup
De momento, he localizado el principal culpable: ese 2^k. Lo he cambiado por una tabla y he bajado a los 2m40s.

Re: Rótulos demasiado lentos

Publicado: Vie Sep 04, 2020 3:23 pm
por zup
Con la ayuda de spectrumcomputing, he logrado bajar el tiempo a 35 segundos.

Código: Seleccionar todo

1 DIM b(8): FOR i=1 TO 8: LET b(i)=2^(i-1): NEXT i
10 LET score=23: GO SUB 9998: GO SUB 9950
8999 GO TO 9999
9700 REM PLOT PRINT
9720 LET x1=x: FOR i=1 TO LEN s$: LET x1=x1+8*pw: IF s$(i)=" " THEN GO TO 9840
9730 LET dir=8*( CODE s$(i))+PEEK 23606+256*PEEK 23607
9740 FOR j=0 TO 7: LET byte=PEEK dir: IF byte=0 THEN GO TO 9830
9745 LET y1=175-y-j*ph
9750 FOR k=7 TO 0 STEP -1: LET bit=b(k+1): IF byte<bit THEN GO TO 9820
9760 FOR l=1 TO ph
9790 PLOT x1-k*pw,y1-l: DRAW pw-1,0
9810 NEXT l: LET byte=byte-bit: IF byte=0 THEN GO TO 9830
9820 NEXT k
9830 LET dir=dir+1: NEXT j
9840 NEXT i
9850 RETURN 
9950 REM GAME OVER
9951 BORDER 2: PAPER 2: INK 7: CLS 
9952 LET s$="GAME OVER": LET pw=2: LET ph=3: LET y=50: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9953 LET s$="Score: ": FOR i=1 TO 5-LEN STR$ score: LET s$=s$+" ": NEXT i
9954 LET s$=s$+STR$ score
9955 LET pw=2: LET ph=2: LET y=100: LET x=(256-LEN s$*8*pw)/2: GO SUB 9970
9956 RETURN 
9970 GO TO 9700
9998 POKE 23672,0: POKE 23673,0: POKE 23674,0: RETURN 
9999 LET time=PEEK 23672+256*PEEK 23673+65536*PEEK 23674: LET horas=INT (time/180000): LET time=time-horas*180000: LET minutos=INT (time/3000): LET time=time-minutos*3000: LET segundos=INT (time/50): LET time=time-segundos*50: PRINT AT 10,0;horas;"h:";minutos;"m:";segundos;"s.";time
Los principales cambios son:
- En vez de usar 2^k, he rellenado una tabla con valores precalculados. Ese 2^k es MUY caro en términos de tiempo.
- En las líneas 9740 y 9810 se comprueba si quedan píxeles por dibujar... de esta manera se ahorran unas cuantas vueltas a los bucles.
- Se ha suprimido el bucle más interior (m), ya que esto se puede dibujar usando DRAW.
- Las dos fórmulas que se usaban para calcular las coordenadas de PLOT han sido divididas, y parte de los cálculos se han movido lo más afuera posible en los bucles. Así se ahorra algo de tiempo haciendo multiplicaciones innecesarias.

Supongo que 35 segundos ya es "cutre" (en vez de mierdoso)... creo que hay hueco para más optimizaciones, pero no creo que sean necesarias (en este contexto).

Re: Rótulos demasiado lentos

Publicado: Sab Sep 12, 2020 10:39 am
por hikoki
Con esta herramienta puedes hacer rotulos cutres
https://drive.google.com/drive/mobile/f ... sp=sharing

Re: Rótulos demasiado lentos

Publicado: Dom Oct 18, 2020 5:05 pm
por Ivanzx
Y qué tal si te atreves con un juego grande, un gran desafío :)