Ahorrar memoria en BASIC ZX Spectrum

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

Avatar de Usuario
AncientBits
Herbert
Mensajes: 99
Registrado: Sab Sep 30, 2017 10:50 am

Ahorrar memoria en BASIC ZX Spectrum

Mensaje por AncientBits » Vie Oct 13, 2017 11:32 am

Hola, estoy haciendo un juego con mucho texto para ZX48K en BASIC puro. Se trata de una aventura al estilo "Elige tu propia Aventura" (que es lo único que sé hacer) pero el texto me come mucha memoria.

En anteriores juegos que hice usé el truco de asignar con LET a$ y siguientes las frases o palabras largas que más se repetían en el juego. Por ejemplo...

LETa$ = "Pulsa X para continar"
LETb$ = "¿Qué camino vas a elegir"
LETc$ = Recuerdos de Constantinopla
Etc.

Eso me ahorra unos 700kb o así al final del juego, pero querría saber si hay más trucos o maneras de comprimir el texto en BASIC o similar.

Hace 10 años ya pregunté sobre este tema, así que imagino que no habrá mucho más que hacer pero por intentarlo... :roll:

http://computeremuzone.com/forum/viewtopic.php?t=2915


Gracias!
Imagen

Imagen

Imagen

Avatar de Usuario
Scooter
Freddy Hardest
Mensajes: 711
Registrado: Jue Nov 11, 2010 10:17 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por Scooter » Vie Oct 13, 2017 4:40 pm

Pues si que hay sistemas pero no son sencillos.
Se me ocurre que pongas en un archivo de texto todos los mensajes de tu programa, con el buscador veas que palabras largas son las diez más repetidas y las sustituyas por ejemplo por %0, %1 etc...
Cuando "imprimas" la cadena tienes que buscar el símbolo % , leer el carácter que le sigue e imprimir la cadena(índice) de paso les añades los espacios de delante y detrás.

Así la cadena "Yo vivo en Constantinopla dos años" quedaría como "yo vivo en%3dos años" ahorrando 14 bytes por cada repetición a partir de la segunda aparición.
Si Constantinopla está cien veces ahorras 1400 bytes
Claro, eso consume CPU.
Obviamente no ganas nada si lo que cambias tiene dos o tres letras

Enviado desde mi 5056D mediante Tapatalk
Aquellos chalados en sus viejos cacharros...

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Vie Oct 13, 2017 4:48 pm

AncientBits escribió:Hola, estoy haciendo un juego con mucho texto para ZX48K en BASIC puro. Se trata de una aventura al estilo "Elige tu propia Aventura" (que es lo único que sé hacer) pero el texto me come mucha memoria.
Creo que hay algún programa para hacer ese tipo de juegos, que imagino comprimirá el texto. Los creadores de "visual novel" también te deberian ayudar.
AncientBits escribió:Eso me ahorra unos 700kb o así al final del juego, pero querría saber si hay más trucos o maneras de comprimir el texto en BASIC o similar.
700 kb. Eres mi héroe.
Scooter escribió:Así la cadena "Yo vivo en Constantinopla dos años" quedaría como "yo vivo en%3dos años" ahorrando 14 bytes por cada repetición a partir de la segunda aparición.
En BASIC podrías hacerlo con una matriz de cadenas con las palabras más frecuentes (p.ej.: p$) y la sentencia sería algo así como

Código: Seleccionar todo

PRINT "Yo vivo en ";p$(3);" dos años"
Esto tiene un pequeño problema y es que los números en el Spectrum ocupan 5 bytes. En realidad, p$(3) ocupa 10 bytes lo que ocupa más que la mayoría de palabras.

Muchas aventuras gráficas crean "diccionarios", de manera que cada palabra ocupa uno o dos bytes en memoria. Habría que hacer unos cuantos malabarismos, pero el ahorro de memoria sería brutal.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
Scooter
Freddy Hardest
Mensajes: 711
Registrado: Jue Nov 11, 2010 10:17 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por Scooter » Vie Oct 13, 2017 9:45 pm

Yo no he dicho de cortar la cadena.
Yo pondría la cadena "Yo vivo en%3desde agosto"
Pero para imprimir la cadena usaría un "parser" que hiciera un for hasta el Len De la cadena e iría imprimiendo hasta llegar al% y a continuación cambiaría la cadena.
No sé si el basic es lo bastante largo para hacer eso o no.
Al menos lo intentaría a ver qué pasa.

Algo así:
For x = 1 to Len(cadena$)
If mid$(cadena$,x,1)="%" then gosub 1000
Print mid$(cadena$,x,1);
Next x

1000
X=x+1
Indice= mid$(cadena,x,1)
X=x+1
If indice ="1" then print" cosa1 ";: return
If indice ="2" then print" cadenaslarga2 ";:return
...
...

No sé si eso es viable en zxbasic. En el cutrebasic V2 del c64 si que lo sería...previo ajustes variados, ya que esto es un pseudicódigo

Si hace falta se pueden usar todas las letras para las primeras 34 cadenas repetitivas, contando números y letras


Enviado desde mi 5056D mediante Tapatalk
Aquellos chalados en sus viejos cacharros...

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Sab Oct 14, 2017 12:13 am

Scooter escribió:Yo no he dicho de cortar la cadena.
Yo pondría la cadena "Yo vivo en%3desde agosto"
Pero para imprimir la cadena usaría un "parser" que hiciera un for hasta el Len De la cadena e iría imprimiendo hasta llegar al% y a continuación cambiaría la cadena.
O usar caracteres por encima de 127 (los TOKENs) para representar hasta 128 palabras. Los problemas de estas soluciones son dos:
- ¿El BASIC será suficientemente rápido para tratar la cadena sin ralentizar mucho el texto?
- Codificar a mano las cadenas es un coñazo.

El primer problema se soluciona tirando de c/m, y el segundo... habría que hacer una utilidad que codificara los textos y generara el BASIC correspondiente.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

K.O.D.
Jack The Nipper
Mensajes: 115
Registrado: Mar Sep 30, 2008 8:45 am
Ubicación: Valencia

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por K.O.D. » Sab Oct 14, 2017 2:11 am

Me viene ahora a la cabeza este programa, igual ya lo conoces:

http://sol.gfxile.net/mucho/mucho.html

No lo he usado pero le he dado un vistazo a las aventuras que vienen en .tap (están todas en inglés, of couse) y bueno no se ve mal, pero si ya tienes todo el código y demás, igual no es buena idea

Salu2

K.O.D.
Jack The Nipper
Mensajes: 115
Registrado: Mar Sep 30, 2008 8:45 am
Ubicación: Valencia

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por K.O.D. » Sab Oct 14, 2017 1:14 pm

Tratándose de un proyecto en BASIC, estos dos artículos de Francisco León igual te dan alguna idea (o igual ya los conoces), al desarrollar un juego del mismo tipo que el tuyo:

- http://trastero.speccy.org/cosas/FLeon/ ... gramas.txt
- http://trastero.speccy.org/cosas/FLeon/ ... turas1.txt

El objetivo del autor (que consigue, obviamente) es crear una aventura tipo libro-juego con más de 100K de texto desde BASIC, empleando técnicas que detalla muy bien. Creo recordar que consigue 160k de texto en la versión +3.

Un saludo.

Avatar de Usuario
Scooter
Freddy Hardest
Mensajes: 711
Registrado: Jue Nov 11, 2010 10:17 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por Scooter » Sab Oct 14, 2017 9:19 pm

Pues si, usar los caracteres altos me parece mejor opción que el carácter comodín, se ahorra algún byte y es un poco más rápido.

Coñazo relativo, sería cosa de hacer el trabajo en un PC con la opción buscar y reemplazar de un editor de textos.
Primero contar palabras repetidas y luego reemplazar.

Enviado desde mi 5056D mediante Tapatalk
Aquellos chalados en sus viejos cacharros...

Avatar de Usuario
AncientBits
Herbert
Mensajes: 99
Registrado: Sab Sep 30, 2017 10:50 am

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por AncientBits » Mar Oct 17, 2017 12:47 am

Gracias chavales por vuestra ayuda! Estoy leyendo e intentando asimilar el tutorial de Francisco León para enlazar programas como si fueran uno solo y también echando un vistazo al MuCho que habéis nombrado.

Debo decir que se escapan un poco a mi comprensión, pero llego a entender algo. Si finalmente no llego a darles utilidad práctica espero que al menos algo se me quede... :wink:

Yo inocentemente pensaba que habría algún programa milagroso que me introdujera un código de compresión de texto o algo así...





zup escribió:
AncientBits escribió:Eso me ahorra unos 700kb o así al final del juego, pero querría saber si hay más trucos o maneras de comprimir el texto en BASIC o similar.
700 kb. Eres mi héroe.

:lol: Je, je... ahí veis el nivel "Total Pro" que llevo... ¡Con esos 700Kb mis problemas estarían resueltos! :lol:
Imagen

Imagen

Imagen

Avatar de Usuario
AncientBits
Herbert
Mensajes: 99
Registrado: Sab Sep 30, 2017 10:50 am

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por AncientBits » Vie Feb 02, 2018 11:17 am

Hola, finalmente ya terminamos el juego "Vindius - The Videogame". Voy a poner aquí algunos de los "trucos" que hemos usado para ahorrar memoria en un juego de este tipo (aventuras de texto estilo "Elige tu Propia Aventura"), por si algún otro cenutrio sin conocimientos de programación se anima a hacer algún juego similar pueda servirle de algo...



1) USO DE VARIABLES PARA PALABRAS LARGAS O FRASES QUE SE REPITEN MUCHO

Como ya dije, este truco ya lo usé en anteriores juegos de Ancient Bits. Consiste en asignar variables a palabras o frases largas, de modo que cuando se repiten tan sólo tienes que poner la variable. Por ejemplo:

LETa$ = "Pulsa X para continar"
LETb$ = "¿Qué camino vas a elegir"
LETc$ = Recuerdos de Constantinopla

Así, si se repite mucho la frase "¿Qué camino vas a elegir?" puedes poner simplemente PRINT b$. Esto normalmente da para un ahorro de entre 700-900 bytes.




2) RENUMBER PROGRAM

BASin (e imagino que otros editores de BASIC) tiene una opción que renumera todas las líneas del programa. Normalmente programamos numerando de 10 en 10 por si se te olvida poner algo tener hueco. En estos juegos de "Elige tu Propia Aventura" normalmente me salen más de 150 líneas.

Al renumerarlas de 1 en 1, los dígitos de línea que se ahorra dan para unos 100-150 bytes más. Es importante hacer este paso SIEMPRE al final, cuando ya estás seguro que todo funciona correctamente y guardar una copia del antiguo por si hay algún error.



3) IF A=1 THEN YOU CAN SAVE MANY MEMORY

En estos juegos "Elige tu Propia Aventura" es habitual tener que recurrir a los comandos IF, THEN, GO TO... para dar las distintas opciones para que el jugador elija. Yo siempre lo hacía así...

Código: Seleccionar todo

10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 IF A=1 THEN GO TO 100
40 IF A=2 THEN GO TO 150
50 IF A=3 THEN GO TO 150
100 PRINT "Enhorabuena derrotas al monstro"
150 PRINT "El monstruo te ha matado"
Pues bien, en casos como este en el que SÓLO UNA RESPUESTA ES LA CORRECTA, podemos ahorrar mucha memoria haciendo lo siguiente...

Código: Seleccionar todo

10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 IF A=1 THEN GO TO 100
40 GO TO 150
100 PRINT "Enhorabuena derrotas al monstro"
150 PRINT "El monstruo te ha matado"
Como estos casos pueden repetirse bastantes veces a lo largo del juego, esto al final nos da para un ahorro de uno 200 bytes. Pero insisto, sólo en casos en los que 1 respuesta es válida y las otras te llevan a un mismo camino (normalmente la muerte).




4) PASAR FUENTES EN FORMATO HEXADECIMAL EN VEZ DE DECIMAL

En BASin, a la hora de poner fuentes personalizadas, las líneas DATA que contienen los gráficos de las fuentes nuevas pueden enviarse como DATA DECIMAL o DATA HEX.

En la versión antigua que yo usaba de BASin sólo se podía BASIC DATA (DECIMAL) y era un porrón de números que ocupaban la friolera de 7 Kb... Con la versión BASin C 1.69 se pueden enviar exactamente igual pero en formato HEX, ocupando mucho menos, ahorrando nada más y nada menos que casi 5 Kb!!!




Bueno, pues espero que a alguien le sea de utilidad en futuros juegos de "Elige tu Propia Aventura" como los que nos enseñó a hacer Radastan en Bytemaniacos.com.

Un saludo y gracias a todos!
Imagen

Imagen

Imagen

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Vie Feb 02, 2018 2:07 pm

La forma que más memoria ahorra con las fuentes es usar LOAD ""CODE :D

Elaborando un poco el tema... La norma 4 yo diría que está mal del todo. La norma debería decir:

4) NUNCA DEFINAS BINARIOS EN BASIC...

Meter un montón de DATAs y las instrucciones que las cargan en memoria ocupa un montón de BASIC que podrías usar para otras cosas. En el caso concreto de Vindius, son como 2K. Comparado con un simple LOAD "" CODE (4 bytes, 8 bytes si va solo en una línea) el ahorro es brutal.

4a) ...PERO PUEDES INCRUSTARLOS EN LÍNEAS REM

Es una técnica que se usa en algunos cargadores de juegos. Las ventajas son ahorrarse ese LOAD ""CODE y no necesitar el uso de CLEAR para reservar memoria al código.

El problema (y gordo) es que una vez hecho esto, el BASIC pasa a ser casi ilegible.

En el caso del Vindius, los DATA de la línea 132 también son buenos candidatos a cargarlos como CODE (en cuyo caso tendrías que leerlos con PEEK). Los BEEP del principio (línea 16) son otra cosa, ya que no son enteros (ese 0.3 no puede codificarse en un solo byte).

Otros cambios y sugerencias...

1) USO DE VARIABLES PARA ELEMENTOS QUE SE REPITEN MUCHO

Además de para las frases, puedes utilizarlo para números. Por ejemplo, LET z=0 ocupa 8 bytes, pero usar z a posteriori te ocupará solo 1. Cero y uno son bastante comunes, puedes ahorrar montones de bytes con ellos.

5) USO DE EXPRESIONES PARA AHORRAR MEMORIA

Viejo conocido cuando andas muy escaso de memoria, en realidad intercambias memoria de BASIC por uso del calculador. El ejemplo más típico es usar NOT PI en vez de 0, ahorras 3 bytes. Combinado con la anterior, podrías usar estas dos instrucciones
LET Z=NOT PI: LET U=PI/PI y ahorrar mucha memoria cada vez que necesites un cero o un uno suelto.

Otro ejemplo (discutible) se puede usar jugando con tu ejemplo del monstruo y el hacha:

Código: Seleccionar todo

10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 IF A=1 THEN GO TO 100
40 IF A=2 THEN GO TO 150
50 IF A=3 THEN GO TO 150
100 PRINT "Enhorabuena derrotas al monstro"
150 PRINT "El monstruo te ha matado"
Si lo modificas a algo así, se ahorra "algo" de memoria a cambio de mayor complejidad:

Código: Seleccionar todo

10 PRINT "Te encuentras con un mostruo horrible, ¿qué vas a hacer) 1) Ataca con espada 2) Ataca con hacha 3) Ataca con lanza"
20 INPUT A
30 GO TO 50*A+50
100 PRINT "Enhorabuena derrotas al monstro"
200 PRINT "El monstruo te ha matado"
Al evaluar A, el Spectrum saltará a las líneas 100, 150 (que no existe) y 200, ahorrándote las líneas 40 y 50. El problema de esta técnica es que tienes que ordenar el código bien y que va a ser incompatible con los renumeradores de líneas (que no evalúan ni sustituyen expresiones). En este caso, puede que la mayor complejidad no compense.

Por último, recordar que cada número "a pelo" va acompañado por otros 5 bytes que lo expresan en coma flotante. Usando la expresión VAL "60000" (por ejemplo", el número 64000 deja de tener esa coletilla. Poner VAL por todas partes es un peñazo, aunque ahorras algunos bytes, y tiene la pega de que necesita memoria en el calculador. Si tienes un CLEAR muy bajo, puede que usar VAL haga que casque el programa.

Eso sí, en algunos casos puede ahorrar bastante memoria. En la línea 129, la expresión 1/51 ocupa 16 bytes, mientras que VAL "1/51" ocuparía solo 7.

6) PRECARGA DE VARIABLES

Otra técnica compleja, a usar en combinación con la técnica 1 y únicamente si no vas a usar CLEAR en todo el programa.

En un Spectrum, las variables nunca se borran hasta que sucede un CLEAR o un RUN (lógico). Otro asunto interesante es que SAVE no graba el programa, sino el programa y las variables que estuvieran definidas en ese momento. De manera que yo podría hacer una "burrada" tal que esta...

Código: Seleccionar todo

10 LET a$ = "Pulsa X para continar"
20 LET b$ = "¿Qué camino vas a elegir"
30 LET c$ = Recuerdos de Constantinopla
40 STOP
50 REM El programa real empieza aquí
En las líneas 10 a 30 se definen las variables, y la línea 40 para el programa con las variables ya definidas. La línea 50 y posteriroes serían tu aventura.

En este punto ejecuto el programa que acaba con un STOP. Ahora borro las líneas 10 a 40 y hago un SAVE. El programa que he grabado tendrá en memoria a$, b$ y c$ pero no habré gastado ni un byte de BASIC en definirlas, ahorrándome unos cuantos bytes más.

7) NO HAGAS OPERACIONES QUE NO NECESITAS

Concretamente, mirando la línea 2 del Vinius:

Código: Seleccionar todo

2 POKE 23606,64000-256*INT(64000/256): POKE 23607, INT (64000/256)
Esta forma de calcular POKEs está muy bien si partes de una variable, pero no si es una constante. Es algo que podrías haber hecho con una calculadora y ahorrarte bytes. Resumiendo, esta línea debería ser la siguiente:

Código: Seleccionar todo

2 poke 23606,0: poke 23607,250
Los valores los he calculado con una calculadora, y con eso me he ahorrado (a bulto) unos 50 bytes. Lo mismo pasa en las líneas 128 y 129 (las que calculan ciertas constantes para los BEEP). En el caso de la línea 129 LET MININ=1/(51+0) el cero sobra y podría haberse puesto como 129 LET MININ=1/51 (te ahorras los paréntesis, el cero y su representación en coma flotante).

Otros caso es la línea 101 (hay más como esta) que tiene un PRINT "";F$;"detuvo a...". Estás imprimiento una cadena vacía. Esto es equivalente a PRINT F$;"detuvo a..." y te ahorras 3 bytes (las dos comillas y el punto y coma).

8) SUBRUTINAS

Si tienes conjuntos de operaciones que se repiten constantemente (p.ej.: esos conjuntos CLS:PRINT:PAUSE) quizás puedas ahorrar algo usando GO SUB.

En el caso concreto del Vindius, "arreglar" esos PRINT para convertirlos en variables y pasarlos a las rutinas GOSUB haría que el programa resultante ocupara más espacio (por los códigos de control)... no merece la pena.
Última edición por zup el Sab Feb 03, 2018 10:57 pm, editado 1 vez en total.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Sab Feb 03, 2018 11:32 am

Otras cuestiones que te interesan...

Como ya he dicho, las variables permanecen hasta que haces un CLEAR. En el caso del Vindius, el BASIC se salvó después de haber sido ejecutado, con lo cual hay alguna variable usada. No es más molestia que esto alarga un poco el tiempo de carga (y que te deja algo menos de BASIC cuando estás editando). Antes de grabar un juego, usa CLEAR para evitarlo (a menos que uses la técnica de variables precargadas).

En un Spectrum, la instrucción CLEAR hace 3 cosas:
- Borra las variables.
- Si tiene un número detrás, pone RAMTOP en ese número y mueve la pila debajo.
- Borra la pantalla.

En el caso de Vindius, lo interesante es la segunda opción. Ni el BASIC ni la pila jamás corromperán lo que haya por encima del CLEAR. ¿Por qué es interesante? Porque has puesto la fuente a partir de 64256. Si tu programa ocupara una burrada de memoria, la hacer POKEs estarías POKEando sobre el propio programa. Si tu programa necesitara usar mucho la pila (muy improbable), la pila podría colisionar con tu tipo de letra y joderlo.

Si haces un CLEAR 64255 al principio del programa consigues que la pila nunca fastidie tu tipo de letra y que si tu programa ocupa demasiada memoria no lo corrompas (si el programa es muy largo al hacer el CLEAR tendrías un error RAMTOP no good, y si ocupas demasiadas variables tendrías un error Out of memory). En general, si vas a necesitar sitio para un binario (en este caso el tipo de letra) SIEMPRE debes usar un CLEAR para reservarle memoria.

Y como CLEAR borra la memoria, puede sustituir al primer CLS del programa. En algunos cargadores meten BORDER, PAPER, INK, CLS en una línea y luego en la siguiente hacen algún POKE y un CLEAR... cuando podrían hacer BORDER, PAPER, INK, CLEAR y ahorrar algún byte suelto.

(Advertencia... en un programa BASIC solo debería haber un CLEAR o te cargarás las variables ya definidas)

A ver si puedo ponerme esta tarde a destriparte un poco el Vindius y cargo una cinta que muestre el uso de estas técnicas...
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Sab Feb 03, 2018 11:03 pm

He creado un archivo 7z que contiene mis modificaciones al Vindius en castellano para ahorrar algo de memoria, junto con un archivo txt que tiene las notas de qué se ha hecho a cada versión. Se puede descargar desde aquí (link público en mediafire).
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Avatar de Usuario
AncientBits
Herbert
Mensajes: 99
Registrado: Sab Sep 30, 2017 10:50 am

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por AncientBits » Dom Feb 04, 2018 1:24 am

¡JesuCristo del amor hermoso! :shock:

¡Menudo trabajo te has pegao ZUP! Pero te lo agradezco enormemente, porque no sólo me va a servir de ayuda para próximos proyectos (tenemos pensado hacer otro juego de formato similar en verano), sino porque además me ha servido para entender algunas cosas que durante el desarrollo del Vindius tan sólo pude ir haciendo a base de ensayo/error sin entender el por qué.

Aunque tengo que leerlo más a fondo y probar en BASin algunas de los "trucos" que comentas, te explico por qué no pude hacer algunos de ellos pese que me lo indicaste en otros posts...

7) NO HAGAS OPERACIONES QUE NO NECESITAS

Concretamente, mirando la línea 2 del Vinius:

2 POKE 23606,64000-256*INT(64000/256): POKE 23607, INT (64000/256)

Ya en el otro post vi que tú pusiste la dirección del pokeo en 2 números, sin usar la expresión entera que sale en el manual. Te juro que lo intenté calcular con calculadora pero no fui capaz (no sé qué cálculo hacía mal que me salían números con decimales). No me quedó otra que poner toda la expresión completa.





4) NUNCA DEFINAS BINARIOS EN BASIC...

Meter un montón de DATAs y las instrucciones que las cargan en memoria ocupa un montón de BASIC que podrías usar para otras cosas. En el caso concreto de Vindius, son como 2K. Comparado con un simple LOAD "" CODE (4 bytes, 8 bytes si va solo en una línea) el ahorro es brutal.

Lo mismo. Ya me lo indicasteis tanto tú como rmartins en otro foro y no fui capaz de hacer un LOAD CODE con BASin.

Esto ya me pasó incluso antes de comenzar al programar el juego intentando cargar las fuentes especiales FZX:

http://foro.speccy.org/viewtopic.php?f=6&t=3329

Mira que pone bien simple cómo hacerlo, pero yo con BASin no fui capaz de cargarlas... Así que el único método fue meterlas en la memoria del propio programa a costa de unos 2.5Kb (que ya me pareció una maravilla después de haber visto los 7Kb de los DATA decimales).




CLEAR 64255
Originalmente el programa tenía un CLEAR donde tenía que ir. Pero como ya tenía el resto del programa escrito, al poner ese CLEAR si la dirección de memoria estaba ocupada me borraba esa parte de memoria (además el BASin me avisaba al llegar al CLEAR).

Recuerdo que lo dejé sólo hasta que vi que no me daba el error, y luego tuve que quitarlo porque creo recordar que me borraba las variables o algo pasaba. Pero quitándolo no había problema y todo funcionaba bien.



Pues nada, gracias por el trabajo que te has pegado. Como digo, lo valoro más como lección magistral de BASIC que por el ahorro de memoria en sí. Lo pondré en el hilo original del Vindius para que lo vean los compañeros del equipo "V".

Gracias ZUP!


P.D.: ¿Cómo has podido ver el código del Vindius desde el archivo .tzx? Dicen que puede conocerse a un programador viendo su código... ¡¡no quiero ni imaginar la imagen que te habrás llevado de mi!! :lol:
Imagen

Imagen

Imagen

zup
Freddy Hardest
Mensajes: 666
Registrado: Vie Ago 15, 2008 2:43 pm

Re: Ahorrar memoria en BASIC ZX Spectrum

Mensaje por zup » Dom Feb 04, 2018 9:29 am

AncientBits escribió:Ya en el otro post vi que tú pusiste la dirección del pokeo en 2 números, sin usar la expresión entera que sale en el manual. Te juro que lo intenté calcular con calculadora pero no fui capaz (no sé qué cálculo hacía mal que me salían números con decimales). No me quedó otra que poner toda la expresión completa.
Es que muchas veces salen decimales. Primero haz la segunda parte del invento con la calculadora (pongamos que quieres dividir el número 50000):

50000/256=195.3125 --> De aquí te quedas la parte entera (195) y la pokeas. Para el siguiente POKE toca esto:

50000-(256*195)=80 y ya tienes el siguiente POKE.

En esta me pillaste... yo estaba convencido de que los POKEs debían apuntar a la dirección el font (64256) cuando en realidad deben apuntar 256 bytes más abajo.
AncientBits escribió:...y no fui capaz de hacer un LOAD CODE con BASin.

Ni lo he intentado. Simplemente pon todas esas instrucciones en una línea con un REM y cuando acabes con el juego quitas el REM y usas alguna utilidad para poner el bloque CODE en su sitio.

En mi caso use ZX Spin para hacer un SAVE del bloque de código en un tzx nuevo.
AncientBits escribió:Originalmente el programa tenía un CLEAR donde tenía que ir. Pero como ya tenía el resto del programa escrito, al poner ese CLEAR si la dirección de memoria estaba ocupada me borraba esa parte de memoria (además el BASin me avisaba al llegar al CLEAR).
BASIN te avisa (supongo) porque el BASIC ya no te cabe en el Spectrum. Al quitar el CLEAR, BASIN te avisará cuando te aproximes a la dirección 65368 (que es el CLEAR por defecto del Spectrum) pero si no has reservado sitio para el font al hacer los POKEs machacarás el BASIC.
AncientBits escribió:P.D.: ¿Cómo has podido ver el código del Vindius desde el archivo .tzx? Dicen que puede conocerse a un programador viendo su código... ¡¡no quiero ni imaginar la imagen que te habrás llevado de mi!! :lol:
El juego es en BASIC, así que tienes montones de opciones para verlo:
- BASIN te deja leer ficheros .tzx (aunque la versión que tengo se atasca con los códigos de control y los binarios).
- Hay herramientas en el Spectrum para listar programas en BASIC. Yo recomiendo el Listador BASIC para +3 de la Microhobby 192 y (si este falla) el BASIC LIST de Johnny EJS. El de Microhobby tiene más opciones, pero el de Johnny EJS puede cargar listados más largos.
- En este caso, como el juego no está protegido de ninguna manera, puedes usar un MERGE "".

Lo que me intriga es cómo has hecho las pantallas... ¿has usado algún editor?
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start...

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 12 invitados