Skip to content

AmstradGameDevChallenge/BASICvsC-RPG

Repository files navigation

BASIC vs C: RPG

Desarrollo en directo de un juego de rol en BASIC y C para Amstrad CPC.

Seguidnos en Twitter: @FranGallegoBR, @Hec_Linares, #TeamBASIC, #TeamC, #AmstradGameDevChallenge

EPISODIO 4: Especial Gráficos UDG #AGC04

Amstrad GameDev Challenge: BASIC vs C. Episodio 4. Especial Gráficos UDG. #AGC04 Fecha: Martes, 27 de agosto de 2019, 21:00h

>> Vídeo <<

>> Código fuente << || >> UDG Designer <<


>>> Contenidos detallados <<<
  • Noticias:
    • 4ª edición de los premios de animación de la comunidad de Madrid, con premios de 2000€ y 1000€ a los mejores videojuegos culturales.
    • Actualizaciones de CPCtelera
      • cpct_rvm ahora soporta uso de nombres largos y modo warp en arranque.
      • cpc2cdt permite importar ficheros ASCII en CDTs.
      • cpct_pack permite la generación de ficheros binarios comprimidos.
      • cpct_bin2sna permite crear snapshots de múltiples ficheros binarios.
    • Nueva versión del emulador CPCEC de CNGSoft. Funciona en Windows y en Linux/Mac (con wine).
  • Desarrollo:
    • BASIC:
      • Repaso del código BASIC: uso de fre("") y UNT()
      • Reestructuración del código de gestión de enemigos y personaje principal
      • Descarga directa y uso en línea de comando de la última versión del emulador de CNGSoft CPCEC (wget http://cngsoft.no-ip.org/cpcec-20190817.zip)
      • Sustitución de mensajes por gráficos: usando subrutinas de dibujado para personaje y enemigos
      • Uso de variables temporales para acortar el código y mejorar su legibilidad
      • Introducción a los gráficos UDG: ¿Qué son? ¿Cómo se crean? Definición y uso de distinas bases numéricas.
      • Uso de SYMBOL y SYMBOL AFTER.
      • ¿Por qué es necesario SYMBOL AFTER? Uso de memoria de los UDGs. Modificación a mano de la memoria que define los UDGs.
      • Presentación de hoja de cálculo para dibujado de UDGs.
      • Soporte para que los enemigos puedan tener sus propios UDGs
      • Más información sobre gráficos UDG en el blog de Fremos.
      • Dibujado de sprites formados por múltiples caracteres y con varios colores: uso del modo transparente.
      • Dibujando sprites multicolor y multicarácter usando cadenas y códigos de control: String Sprites
      • Definición de String Sprites constantes en un array, accesibles por su índice: evitando copiar cadenas en tiempo de ejecución.
      • Activación/Desactivación de modo transaparente usando cadenas y el código de control 22
    • C:
      • Problemas de SYMBOL AFTER en C:
        • No hay SYMBOL AFTER en C ni en el firmware de Amstrad.
        • En C se generan binarios, y al cargar un binario Amstrad desactiva los UDGs.
      • El firmware almacena 3 variables en memoria para gestionar los UDG: Valor ASCII del primer UDG definible, Puntero a la matriz de UDGs y flag de activación.
      • Las variables están en ubicaciones distintas en los firmwares 1.0 y 1.1.
      • Implementación de SYMBOL AFTER en C.
      • Detalle sobre el casting de direcciones de memoria absolutas a punteros.
      • Implementación de SYMBOL en C usando el código de control 25.
      • Entendiendo HIMEM, el firmware y la ROM, para saber dónde ubicar la tabla de definiciones de UDG para C.
      • Problema: realizar un SYMBOL AFTER antes de la inicialización de texto y gráficos con los CALL 0xBBFF y call 0xBB4E (initMode()). Estas inicializaciones deshacen el SYMBOL AFTER.
      • Detección de la versión del firmware actualmente en ejecución: Usando el final de la tabla de saltos (High jump-block) que es distinto en las 2 versiones.
      • Problema en SDCC con múltiples comparaciones en una misma línea.
      • Definición de múltiples caracteres en C sin usar SYMBOL: haciendo que el puntero de SYMBOL AFTER apunte a un array con los datos.
      • Imprimiendo sprites de enemigos formados de varios carácteres.
      • Creación manual de string sprites en arrays para dibujar enemigos multicaracter y multicolor.
      • Dibujando enemigos con 2 caracteres de altura, 3 colores y 9 UDGs en total.
      • Uso del modo transparencia con una función de activación/desactivación.
    • Nuevos misterios y trabajo para casa:
      • Nuevo problema de memory leak en BASIC: en cada nueva ejecución del juego desaparecen 48 bytes. ¿Por qué?
      • Los UDG en BASIC nos ocupan doble: el código que genera los datos de los UDG, más los propios datos de los UDG.
      • ¿Es posible tener en BASIC en memoria sólo los datos de los UDG, sin el código que los genera, como en C?

AVANCE EPISODIO 4: Misterio Memory Leak en BASIC

Avance Amstrad GameDev Challenge: #TeamBASIC misterio memory leak

Fecha: Martes, 20 de agosto de 2019, 21:00h

>> Vídeo <<

>> Código fuente <<


>>> Contenidos detallados <<<
  • Noticias:
    • Actualización de #CPCtelera: añadido modificador -w para activar el modo Warp al inicio en RVM
  • Misterio en BASIC:
    • Recordatorio: al realizar varios ciclos de ejecución de nuestro juego, durante la ejecución, se pierden bytes de memoria
    • Comentarios de usuarios que han investigado y se han planteado dudas
    • Si la memoria se va perdiendo, ¿Se quedará nuestro programa al final sin memoria?
    • Usuario comenta que parece pederse la memoria en los INPUTs, que parece un fallo del firmware del #Amstrad
    • Revisión de la dirección de memoria &B08D que contiene datos del firmware: 'Final del espacio libre: byte antes de la zona de strings = HIMEM'
    • Detalle importante: hay 2 firmwares de Amstrad CPC, el 1.0 y el 1.1. Las variables del firmware están en direcciones distintas según la versión del firmware
    • Mapa básico de memoria del Amstrad CPC y definición de qué es HIMEM
    • Funcionamiento de los bancos de memoria y las ROMs del CPC a nivel básico
    • HIMEM: dirección más alta de espacio para el programa en BASIC (código y variables)
    • La zona de memoria de BASIC está protegida por el intérprete: no nos permite escribir en ella desde fuera.
    • La orden MEMORY sirve para cambiar HIMEM de posición: utilidades
    • Vemos el valor de HIMEM desde BASIC, usamos HEX$ para convertirlo y vamos a esa zona de memoria a ver qué hay
    • Cómo configurar el visor de memoria de RVM para mostrar contenido de RAM y ROM
    • Ponemos a prueba la zona de strings de BASIC (en HIMEM) asignando valores a a$ y vemos cómo reacciona la memoria
    • La zona de strings de BASIC almacena strings nuevos sin borrar antiguos: funciona como un Stack Allocator (un gestor de memoria tipo pila)
    • Esto explica el misterio: en cada ciclo del programa metemos valores nuevos en los strings con nuestros INPUT.
    • No es realmente un memory leak, sino una consecuencia del Stack Allocator, que funciona similar a lenguajes de script modernos.
    • Es una estrategia óptima para la gestión dinámica de la memoria de strings.
    • ¿Hace este comportamiento que se nos pueda acabar la memoria? Creamos un programa para ponerlo a prueba
    • Cuando no queda memoria, BASIC libera la memoria de strings que ya no son usados, compactando los usados. Básicamente, recolecta la basura.
    • Potenciales ventajas e inconvenientes del funcionamiento de la memoria de strings
    • Controlar y liberar la memoria (recoger la basura) cuando nosotros queramos usando FRE("")
    • Usando UNT para evitar tener que hacer PRINT de FRE("") y no causar Overflows
    • añadiendo la recolección de basura a nuestro programa y poniéndolo a prueba
    • Observando el comportamiento de la memoria cuando forzamos la liberación de strings
    • Truquito en asignación de variables: uso de otras variables en lugar de valores inmediatos
    • Resolución de dudas planteadas en el chat

EPISODIO 3 #AGC03

Amstrad GameDev Challenge: BASIC vs C. Episodio 3. #AGC03

Fecha: Martes, 6 de agosto de 2019, 21:00h

>> Vídeo <<

>> Código fuente <<


>>> Contenidos detallados <<<
  • Noticias:
    • Actualización en CPCtelera 1.5 WIP: Inclusión de soporte para STDC getchar()
    • #AmstradGameDevChallenge estará presente en RetroZaragoza 2019: grabaremos un episodio en directo en persona.
  • Recomendación: temática para los juegos RPG sobre leyendas reales de Castillos, Monasterios, Pueblos o lugares de la geografía española.
  • Preguntas y proyectos de los miembros del grupo:
    • Problema con la inicialización de variables globales en SDCC: no se les asigna valor.
    • Soluciones para variables globales: funciones de inicialización, valores constantes y punteros no constantes y copia de valores con cpct_memcpy
    • Sugerencia de uso de grep para eliminar los comentarios en BASIC.
    • Problema con .gitignore y la carpeta obj/
    • ¿Cómo se puede hacer SYMBOL AFTER en C?
    • Apreciaciones sobre el uso de cpct_setVideoMode, el firmware y las funciones de CPCtelera.
    • Detalles a tener en cuenta en el uso de OPENIN y OPENOUT en BASIC
  • Misterio en BASIC:
    • Pérdidas de memoria en nuestro juego. ¿A qué se deben? Dos semanas para encontrar la respuesta.
  • Desarrollo:
    • Inicialización rápida y fácil de la pantalla, los colores y el módulo de texto sin tener que ajustarlo todo a mano.
    • Llamadas a funciones del firmware con código ensamblador en línea: nota sobre potenciales problemas
    • Creación y manejo de structs en C: ¿Qué son? ¿Cómo funcionan?
    • Introducción de espacio para múltiples enemigos usando un array de structs en C
    • Importancia de los comentarios en BASIC: usarlos como referencia de variables y estructuras de memoria
    • Simulación de structs en BASIC usando arrays y prefijos de nombre
    • Uso de una referencia variable a un elemento para generalizar el código previo directamente
    • Diseño básico de un gestor de enemigos: creación y destrucción
    • Visualización de múltiples enemigos e interacción: problemas asociados
    • Gestión del array de enemigos al eliminar uno de ellos: posibles alternativas
    • Añadiendo color a los enemigos como forma de distinguirlos

EPISODIO 2 #AGC02

Amstrad GameDev Challenge: BASIC vs C. Episodio 2. #AGC02

Fecha: Martes, 23 de julio de 2019, 21:00h

>> Vídeo <<

>> Código fuente <<


>>> Contenidos detallados <<<
  • Noticias:
  • Revisión de proyectos en desarrollo de los miembros del #TeamC y el #TeamBASIC
  • Desarrollo:
    • Creación de un script bash para generar un DSK a partir del fichero .BAS
    • Comentarios que no ocupan memoria en BASIC
    • Reemplazo y uso de variables con nombre corto en BASIC
    • Usando LOCATE desde C para dibujar personajes en una posición concreta
    • Uso de funciones y parámetros en C para reutilizar y simplificar el código
    • Diferencias entre las funciones printf y puts y uso del firmware
    • Análisis de estartegias más óptimas de programación en C usando el código ensamblador generado
    • Uso de las funciones CHR$ y STRING$ en BASIC para pintar caracteres y repetirlos
    • Movimiento de los personajes en una dimensión y ataque por movimiento
    • Uso de GOSUB y subrutinas en BASIC para modularizar el código
    • Dudas sobre paso de parámetros a funciones y subrutinas en BASIC y C
    • Detalle sobre las comparaciones y asignaciones en C
    • Introducción a los arrays en C y BASIC
    • Funciones aleatorias simples para ataques variables en juegos de ROL
    • Definición de funciones matemáticas en BASIC
    • Cálculos enteros y reales y redondeos en BASIC y C
    • Uso de RANDOMIZE para controlar las secuencias pseudoaleatorias

EPISODIO 1 #AGC01

Amstrad GameDev Challenge: BASIC vs C. Episodio 1. #AGC01

Fecha: Martes, 9 de julio de 2019, 21:00h

>> Vídeo <<

>> Código fuente <<


>>> Contenidos detallados <<<
  • Presentación de la serie
  • Herramientas a utilizar y organización
  • Implementado un esquema inicial muy básico de juego y bucle principal emergente, sin apenas estructurar.
  • Primeros pasos con variables
  • Player y enemigo con energía, ataque y defensa
  • Player y enemigo atacan y defienden

Materiales

Cread vuestros repositorios en AmstradGameDevChallenge y empezad vuestros propios RPG en BASIC y C. En el próximo episodio los analizaremos en directo y compartiremos las ideas de programación entre todos.