Programación del Amstrad CPC usando la libreria 8BP ("8 bits de poder") desde BASIC
"Las limitaciones no son un problema, sino una fuente de inspiración"
Jose Javier Garcia Aranda
If you like 8BP, your help is welcome. Help me supporting this initiative (from 1€, whatever you want). Donations will be used for materials and 8BP disemination:
Hoy os voy a contar como actualizar el cartucho DES de 8BP con los últimos juegos. Para ello he grabado un videotutorial que os adjunto en esta entrada.
El cartucho de 8BP contiene una compilación de juegos que podéis disfrutar de forma inmediata (sin necesidad de esperar a cargar la cinta) gracias al dispositivo DES (Dandanator Entertaiment System) , del que tenéis información en https://auamstrad.es/des/ , y donde podréis adquirirlo.
Tendréis que instalar dos cosas en vuestro PC. un driver USB , pues conectareis el PC al DES a través de un cable USB, y el ROM generator 2.4 , que es la aplicación para crear ROMs con colecciones de juegos y para controlar la grabación del cartucho desde el PC. Aquí tenéis los enlaces a todo:
La compilacion de juegos de 8BP en una ROM la teneis en https://github.com/jjaranda13/8BP , en la seccion de "game examples", dentro de "DANDANATOR ROM COLLECTION"
Aqui os dejo el videotutorial que he preparado, bastante casero. Y os adjunto también un video de pablo Forcén, de AUA (video tutorial de Pablo Forcén)
ya tenéis disponible la versión V38 de la libreria 8BP, descargable en github https://github.com/jjaranda13/8BP . Esta nueva versión incorpora las siguientes mejoras:
- detección de colisiones perfeccionada, sin limitaciones por coordenadas negativas
- comando MUSIC mejorado: ahora puedes decidir entra hacer sonar una musica en bucle o hacerla sonar una sola vez.
- el comando MUSICOFF ha sido reemplazado por MUSIC invocado sin parametros
- manual mejorado con capitulo de primeros pasos y diversas pequeñas mejoras
- la librería ocupa exactamente igual que antes (8KB) , dejándote 24 KB para tu lógica BASIC, 8.5 KB para gráficos y 1.4 KB para música
Estos son los primeros pasos con la librería 8BP. Te dejo con un vídeo explicativo y los mismos pasos por escrito, que ademas los tienes en el manual de 8BP que viene con la librería.
Lo primero que debes hacer es instalarte la última versión
de Winape, que es un emulador y a la
vez editor y ensamblador de Amstrad. Lo puedes descargar desde www.winape.net
Una vez instalado el Winape, familiarízate un poco con el,
probando algun juego de Amstrad y probando a cambiar la configuración. Trata de
abrir el assembler que lleva incorporado en el menú y edita un “hola mundo” en
la ventana de ensamblador. A continuación, copia y pega el texto en la ventana
de emulación. Veras como se pega carácter a caracter
Si haces un programa mas largo, para copiarlo en la ventana
de emulación es muy interesante la opción settings->high speed. Verás como
se copia rapidísimo.
Ahora vamos a hacer una primera toma de contacto con 8BP
viendo algunas demos. Entra en el directorio Demos. En el encontraras una serie
de subcarpetas : ASM, BASIC, DSK, MUSIC
Entra en DSK . Alli veras un fichero .dsk con las demos. Desde
winape ve al menú File->drive A-> insert Disc image y selecciona el
archivo de las demos
Una vez seleccionado, desde la ventana de emulación del
Amstrad escribe CAT para ver los archivos
Cada fichero .BAS es una demo donde podrás ver alguna de las
características de 8BP (no todas sus posibilidades se pueden ver con las demos
pero hay algunas representativas).
Ejecuta el comando RUN “LOADER.BAS”. Obtendrás el siguiente
menú:
Ya puedes elegir una demo y probarla. A disfrutar. En el
siguiente y ultimo paso empezaremos la creación de un juego
Hemos probado un fichero .dsk que contiene muchas demos, con
graficos y música. En el directorio Demos/ASM y en el Demos/MUSIC se encuentran
los graficos y la música de las demos que has probado. Sin embargo, si quieres
hacer tu propio juego o demo, es mejor que empieces con unos ficheros “limpios”
sin todos los graficos que requieren las demos que has probado.
Nos vamos al directorio raíz. Alli encontraras una carpeta
llamada 8BP_V38. Yo te recomiendo que hagas una copia de esta carpeta y la
renombres como “mi_juego”. De ese modo preservarás la carpeta 8BP_V38 original
aunque empieces a cambiar cosas
Dentro de la carpeta 8BP_V38 encontraras las carpetas ASM,
BASIC, DSK, MUSIC, TAPE, y output_spedit
Desde la ventana de ensamblador de winape abre el archivo
“ASM/make_all_mygame.asm” y
ejecútalo (simplemente en el menú de winape z80 assembler seleccionas Assemble
o pulsas Ctrl+F9). Esto comenzara a ensamblar (copiar en memoria) la librería y
los graficos en la memoria del Amstrad. En este caso vamos a ensamblar muy
pocos graficos, tan solo los indispensables para un pequeño juego. Los gráficos
se encuentran en images_mygame.asm
Tras ensamblar todo, obtendrás un mensaje como el que se
muestra a continuación:
Pulsas “ok” y desde la ventana de ensamblador vamos a abrir
otro archivo. En este caso vamos a abrir un fichero BASIC, concretamente
“tu_primer_juego.bas” que se encuentra en la carpeta BASIC. Tras abrirlo veras
el siguiente listado en pantalla, que contiene 32 lineas:
Selecciona todo y cópialo. Luego ve a la ventana de
emulación del CPC y pégalo usando el menú FILE->paste
Como el listado es algo mas largo que el “hola mundo”, usa settings->high speed para copiarlo y
luego vuelve al “normal speed”
Como ya esta ensamblada la librería y los gráficos, puedes
hacer RUN y el juego se ejecutará. Debes esquivar unas bolas que caen del cielo
para no morir, moviéndote a derecha e izquierda
Puedes probar a modificar el programa y ver sus efectos.
Poco a poco iras aprendiendo 8BP y podrás hacer modificaciones interesantes
tales como cambiar la frecuencia con la que salen bolas enemigas o su velocidad,
o reemplazar al soldado por una nave espacial y a las bolas por naves enemigas
con diversas trayectorias.
Por último, vamos a crear un disco con tu juego. Para ello,
tras tener el juego funcionanod debes dar estos pasos
·Crea un disco nuevo mediante winape: FILE->
drive A-> new Blanc Disc
·Formatealo:
FILE->drive A->Format Disc Image
·Tras haber creado tu fichero dsk , desde la
ventana de emulación ejecuta los siguientes comandos:
SAVE
“8BP.bin”, b, 24000,18620
SAVE
“juego.bas”
Ya casi hemos terminado. Ahora debes seleccionar otro disco
desde el menú de winape o salir de winape para que el .dsk que has creado se
haga realidad en el sistema de ficheros de windows.
Esta vez os traigo un pequeño tutorial de introducción para hacer un juego tipo "space invaders" en unos minutos. El tutorial está disponible en el canal de vídeos de 8BP https://www.youtube.com/watch?v=6OcB_hjuYiU
Y el juego "mini-invaders" lo encontrareis en la carpeta "Game Examples" del proyecto Github en https://github.com/jjaranda13/8BP Os adjunto aquí el listado del juego. Como complemento a las explicaciones del vídeo os daré algunas pinceladas sobre el listado BASIC del juego que adjunto. - el juego usa 32 sprites - la nave es el sprite 31 - los disparos que puedes lanzar con la nave son el 29 y el 30 - los invaders disparan usando el sprite 28 - los invaders usan los sprites del 0 al 27 (28 invaders en total) - los sprites 31,30 y 29 tienen flag de colisionador activo - el resto de sprites son "colisionados" y tienen flag de colisionado activo - los invasores tienen flag de movimiento automatico activo y se les asocia la ruta "0" que los mueve de derecha a izquierda y hacia abajo, lo típico de los invasores - los disparos de la nave y de los invaders usan una característica de la V27. recorren la pantalla y al salir se desactivan automáticamente con un cambio de estado definido al final de su ruta, simplificando de este modo la lógica de BASIC y por consiguiente acelerando el juego a continuación teneis el listado 10 MEMORY 25999 20 dir=42540:FOR star=0 TO 40 30 POKE dir+star*2,RND*200 40 POKE dir+star*2+1,RND*80 50 NEXT 60 DEFINT A-Z: CALL &6B78:' install RSX 70 |PRINTSPALL,0,1,0:|AUTOALL,1:MODE 0 80 ON BREAK GOSUB 810 90 CALL &BC02:'restaura paleta por defecto 100 INK 0,0:BORDER 1: vidas=3: puntos=0 110 CLS: |STARS,0,10,4,2,0: ciclo=0:counter=0 120 ENT -5,7,10,1,7,-10,1:ENV 1,1,15,1,15,-1,1: 130 'nave 140 |SETUPSP,31,9,16:|SETUPSP,31,0,33:|SETUPSP,31,7,0 150 x=40:y=192:|LOCATESP,31,192,40 160 'fire [29,30] 170 FOR i=29 TO 30:|SETUPSP,i,9,18:|SETUPSP,i,0,0:NEXT 180 disp=0 190 'fire invaders [28] 200 |SETUPSP,28,9,19:|SETUPSP,28,0,0 210 ' invaders [0..27] 220 i=0:FOR yi=0 TO 3 230 FOR xi=0 TO 6 240 |SETUPSP,i,7,1 250 |LOCATESP,i,yi*16+10,xi*8 260 |SETUPSP,i,0,143 270 |SETUPSP,i,15,0 280 i=i+1:NEXT:NEXT 290 'setup colision ------------ 300 collider=0:collided=0:|COLSP,34,4,0 310 |COLSPALL,@collider,@collided:|COLSP,32,0,28 320 'WAIT SPACE TO START -------- 330 PLOT 1,382:DRAW 640,382:|SETLIMITS,1,80,10,200:|PRINTSPALL 340 LOCATE 1,1:PRINT "SCORE";puntos:LOCATE 12,1:PRINT "LIVES:";vidas 350 SOUND 1,25,80,12,,5 360 IF INKEY(47)<>0 THEN 360 370 SOUND 1,100,7,15 380 'ciclo de juego ------------ 390 GOSUB 520:'lectura teclado y movimiento nave y/o disparo 400 GOSUB 630:'disparo invaders 410 ciclo=ciclo+1: IF ciclo>=1048 THEN 110 420 |STARS,0,10,4,1,0 430 |AUTOALL:|PRINTSPALL:|COLSPALL 440 IF collided=32 THEN 390 450 IF collider=31 THEN vidas=vidas-1: IF vidas=0 THEN 690 ELSE 730 460 |SETUPSP,collided,7,2:puntos=puntos+1 470 |SETUPSP,collider,9,17:'borrado del disparo 480 |SETUPSP,collider,15,3 490 SOUND 7,1000,20,15,,,15:LOCATE 7,1:PRINT puntos 500 GOTO 390 510 ' rutina de movimiento nave ----- 520 IF INKEY(27)=0 THEN x=x+1:GOTO 540 530 IF INKEY(34)=0 THEN x=x-1 540 IF counter+8<=ciclo THEN IF INKEY(47)=0 THEN counter=ciclo:GOSUB 580 550 |LOCATESP,31,y,x 560 RETURN 570 ' disparo nave --------------- 580 disp=1+disp MOD 2 590 |LOCATESP,28+disp,y,x+2:|SETUPSP,28+disp,0,169:|SETUPSP,28+disp,15,1:|SETUPSP,28+disp,9,18 600 SOUND 1,25,20,12,,5 610 RETURN 620 ' rutina disparo invaders ---- 630 IF PEEK(27448)<>0 THEN RETURN 640 invader=RND*28:dirinvader=invader*16+27000 650 IF PEEK (dirinvader)=0 THEN RETURN 660 |LOCATESP,28,PEEK(dirinvader+1),PEEK(dirinvader+3):|SETUPSP,28,0,139:|SETUPSP,28,15,2 670 SOUND 1,250,20,12,,5 680 RETURN 690 ' GAME OVER 695 |SETUPSP,31,7,3:|SETUPSP,31,0,143:|LOCATESP,31,186,x 700 LOCATE 7,12:PEN 7:PRINT "GAME OVER" 701 for i=0 to 27:|setupsp,i,0,0:next 702 |PRINTSPALL 710 IF INKEY(47)<>0 THEN 702 ELSE RUN 730 ' rutina muerte nave 740 SOUND 7,1000,20,15,,,15 750 BORDER 7,0 760 |SETUPSP,31,7,3:|SETUPSP,31,0,143:|LOCATESP,31,186,x 770 |PRINTSPALL 780 IF INKEY(47)<>0 THEN 770 790 BORDER 1 800 GOTO 110 810 MODE 2: INK 0,0:PEN 1:BORDER 0: END Por último os adjunto un video tutorial de programación del juego
Os traigo un pequeño tutorial de introducción para hacer un juego tipo "pong" en unos minutos. El tutorial está disponible en el canal de vídeos de 8BP https://www.youtube.com/channel/UCThvesOT-jLU_s8a5ZOjBFA
Os adjunto aquí el listado del juego. Como complemento a las explicaciones del video os diré que la barra del oponente (el ordenador) comienza a tomar decisiones cuando la pelota sobrepasa la mitad del campo, por lo que es posible ganarle. Si le ponemos a tomar decisiones antes llega un momento que es imposible ganar.
Algunas pinceladas sobre el juego:
- COLSPALL : para detectar colisiones entre el "colisionador" (la pelota) y los "colisionados" (las barras). En el byte de estado de los sprites se activa el flag de colisionador para la pelota (sprite 29) y se activa el flag de colisionado en el 31 (nuestra barra) y el 30 (barra del oponente)
- Usa sobreescritura en la pelota para respetar la raya blanca del campo y no borrarla al pasar. Para ello se usa una paleta con sobreescritura y se activa el flag de sobreescritura en el byte de estado del sprite de la pelota (el 29)
- solo hay dos imágenes (la pelota=17 y la barra=16) que se asignan a los 2 sprites (a los sprites 30 y 31 se les asigna la imagen 16 y al sprite 29 se le asigna la imagen 17)
- los sprites usan movimiento automático. Para ello tienen activado el flag de movimiento automático y la instruccion AUTOALL los mueve (les cambia sus coordenadas) de acuerdo a su velocidad
- todos los sprites se imprimen con PRINTSPALL en cada ciclo de juego
Sin más, os dejo con el video tutorial y el listado del videojuego
10 MEMORY 25999 20 DEFINT A-Z: CALL &6B78:' install RSX 21 |PRINTSPALL,0,0:|AUTOALL,0:mode 0 22 on break gosub 2800 26 CALL &BC02:'restaura paleta por defecto 27 INK 0,9 28 INK 1,26 29 INK 4,1 30 ink 6,20: ink 7,20 31 puntosplayer=0 32 puntoscomputer=0 33 LOCATE 5,1:PEN 7:PRINT puntosplayer 34 LOCATE 15,1:PEN 1:PRINT puntoscomputer 35 PLOT 320,0,1:DRAW 320,400: plot 0,300:draw 16,300:draw 16,100:draw 0,100: 36 plot 640,300:draw 640-16,300:draw 640-16,100:draw 640,100 37 border 0 40 'barra del jugador 41 |SETUPSP,31,9,16:|SETUPSP,31,0,11:|LOCATESP,31,80,4 50 ' pelota 51 |SETUPSP,29,9,17:|SETUPSP,29,0,41+64:|LOCATESP,29,90,38:vyp=1:vxp=1 52 collided=0:collider=0:|COLSP,32,30,31:|COLSP,34,4,0 53 |COLSPALL,@collider,@collided 60 'barra computer 61 |SETUPSP,30,9,16:|SETUPSP,30,0,11:|LOCATESP,30,80,74:|SETUPSP,30,5,0,0 62 yc=90 80 |PRINTSPALL 81 env 1,1,15,1,15,-1,1:SOUND 1,100,25,15,1:SOUND 1,100,25,15,1:SOUND 1,100,50,15,1 82 IF INKEY(47)<>0 THEN 82 83 SOUND 1,100,7,15 90 'ciclo de juego------------ 100 GOSUB 220:'lectura teclado y movimiento barra 110 GOSUB 310:'pelota 120 GOSUB 410:'computer 130 |AUTOALL:|PRINTSPALL 140 GOTO 100 200 ' rutina de movimiento barra 220 IF INKEY(67)=0 THEN vy=-5:GOTO 250 230 IF INKEY(69)=0 THEN vy=5:GOTO 250 240 if vy>0 then vy=vy-1 else if vy<0 then vy=vy+1 250 |SETUPSP,31,5,vy 260 RETURN 300 ' rutina movimiento pelota 310 xp=PEEK(27467) 311 IF xp>6 THEN IF xp<70 THEN 345 320 IF xp>=80 THEN GOSUB 500: CLS:GOTO 33:'vxp=-vxp: REM AQUI HAY QUE HACER GOSUB GOL 321 |COLSPALL: IF collider=32 THEN 345 341 IF collided=31 THEN SOUND 1,200,7,15:IF vxp<0 THEN vxp=-vxp:IF vy>0 THEN IF vyp<4 THEN vyp=vyp+1 ELSE ELSE IF vy<0 THEN IF vyp>-4 THEN vyp=vyp-1 342 IF collided=30 THEN SOUND 1,200,7,15:|SETUPSP,30,5,0:IF vxp>0 THEN vxp=-vxp: IF vyp=0 THEN vyp=1 343 pongs=pongs+1: if pongs=10 then vxp=vxp*2 345 yp=PEEK(27465) 346 IF yp<=16 THEN vyp=-vyp:SOUND 1,600,7,15 ELSE IF yp>=192 THEN vyp=-vyp: SOUND 1,600,7,15 347 |SETUPSP,29,5,vyp,vxp 350 RETURN 400 ' rutina movimiento computer 410 IF vxp<0 THEN RETURN:'|SETUPSP,30,5,0:return 411 IF xp<40 THEN RETURN 420 |PEEK,27481,@yc: yc=yc+21 430 IF yc<yp-5 THEN vyc=5: GOTO 450 440 IF yc>yp+5 THEN vyc=-5: goto 450 441 if vyc>0 then vyc=vyc-1 else if vyc<0 then vyc=vyc+1 450 |SETUPSP,30,5,vyc 460 RETURN 500 ' rutina puntos 510 |PEEK,27467,@xp 511 IF xp>40 THEN puntosplayer=puntosplayer+1 ELSE puntoscomputer=puntoscomputer+1 512 pongs=0 520 RETURN 2800 MODE 2: INK 0,0:PEN 1: END
Por petición de algunos foreros de http://www.amstrad.es/forum/ he creado este sencillo videotutorial para introducir en el uso de SPEDIT para crear sprites y usarlos en vuestros programas BASIC hechos con la librería 8BP
El audio en ocasiones es algo malo pero en general creo que puede ser aceptable, ya que una imagen vale mas que mil palabras
En el vídeo se explica como estructurar el juego en carpetas, como usar el emulador "winape" para sacar la salida del SPEDIT a un fichero, ensamblar la librería y los sprites y programar en BASIC vuestro juego, creando unas secuencias de animación con las direcciones en las que se han ensamblado las imágenes
Lo que es inevitable aprender para programar (siempre lo digo) es el significado de la palabra "ensamblar". Que a nadie le de fiebre, saber lo que es ensamblar no significa tener que saber programar en ensamblador.
Espero que lo disfrutéis y sirva para ayudar en la comprensión de esta herramienta