CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Programando el Amstrad en BASIC, C, etc.
Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Jue 27 Jul , 2017 6:13 pm

Bueno, chicos. Después de revisar más a conciencia, tengo que admitir mi parte de culpa en este interesante bug. Hay un detalle interesante, y es que el bug sólo sucede con DSKs previamente creados. Es decir: si hacemos "make cleanall", el bug desaparece, porque el DSK se vuelve a crear de nuevo.

Aquí es donde entra mi parte de la culpa: se supone que el DSK se recreaba en CPCtelera cada vez que se compilaba. Pues bien, revisando me he dado cuenta de que no. En algún momento hice un cambio a una macro que no recrea el DSK, sino que añade ficheros al DSK, creándolo sólo si no existía previamente. Esto es un problema importante, porque ese comportamiento potencia el problema de iDSK. De hecho, me consta que muchos problemas de gente se han resuelto haciendo "make cleanall". Pues bien, es por esto
Acabáramos, ¿me estás diciendo que "make clean" y "make cleanall" son diferentes? Porque yo del primero he hecho unos cuantos...
Conclusión: a todos nos toca recibir nuestro merecido de vez en cuando. Esta vez me toca a mi.
No hombre no, mira que si era porque no hacía "make cleanall" pensando que bastaba con "make clean"...
Lo bueno, eso sí, gracias a la insistencia de @jgonza y a la participación de todos, tenemos este bug corregido. A partir de ahora, la compilación incremental será más útil que antes porque no producirá bugs por culpa de iDSK (por lo menos, no estos bugs).
Si mi pesadez ha servido para algo, ya me doy por satisfecho :oops:
Tenéis el parche subido a la rama master. Pensaré en hacer una bugfix release para que esté disponible por defecto en quienes se bajen la 1.4.2.

Gracias, chicos! :)
A TI POR SUPUESTO!
Visita mi canal de YouTube http://www.youtube.com/c/jgonza

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor ronaldo » Jue 27 Jul , 2017 6:20 pm

Acabáramos, ¿me estás diciendo que "make clean" y "make cleanall" son diferentes? Porque yo del primero he hecho unos cuantos...
Sí, hay una diferencia:
  • make clean: limpia todos los objetos de compilación, pero no toca los resultados (el CDT y el DSK permanencen)
  • make cleanall: limpia todo lo que se genera, objetos y resultados, dejando sólo los fuentes.
Dado que el problema era precisamente la incorrecta regeneración del DSK, make clean no servía para esto.

Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Jue 27 Jul , 2017 6:20 pm

Ahora en seguida pruebo el DSK y te cuento.
Probado con CPCE 1.90, el "kk.bin" hace un reset, el "newkk.bin" no, supongo que eso confirma tus experimentos...

Salu2!
Jorge.
Última edición por jgonza el Jue 27 Jul , 2017 6:20 pm, editado 1 vez en total.
Visita mi canal de YouTube http://www.youtube.com/c/jgonza

Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Jue 27 Jul , 2017 6:24 pm

Sí, hay una diferencia:
  • make clean: limpia todos los objetos de compilación, pero no toca los resultados (el CDT y el DSK permanencen)
  • make cleanall: limpia todo lo que se genera, objetos y resultados, dejando sólo los fuentes.
Dado que el problema era precisamente la incorrecta regeneración del DSK, make clean no servía para esto.
#-o #-o #-o #-o Ya decía Toni que sería una chorrada... "make cleanall" #-o #-o #-o

Bueno, al menos podemos echarnos unas risas ahora <XX
Visita mi canal de YouTube http://www.youtube.com/c/jgonza

Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Vie 28 Jul , 2017 9:02 am

Bueno, confirmado, AHORA YA FUNCIONA !!!
Visita mi canal de YouTube http://www.youtube.com/c/jgonza

Avatar de Usuario
AmstradGamer
Forero habitual
Forero habitual
Mensajes: 189
Registrado: Dom 08 Jun , 2014 10:08 am

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor AmstradGamer » Sab 29 Jul , 2017 1:06 pm

Leyendo el tema del bug, creo que es lo que también me ocurrió inicialmente a mi.

Está bien descubrir estas cosas, aunque sea a las malas!

Un saludo.

Avatar de Usuario
MiguelSky
Lord of Short Time
Lord of Short Time
Mensajes: 6969
Registrado: Sab 08 Oct , 2005 2:02 am
Contactar:

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor MiguelSky » Sab 29 Jul , 2017 1:08 pm

Es como más se aprende ;)

Avatar de Usuario
a13x15
Lechoncillo
Lechoncillo
Mensajes: 15
Registrado: Mié 23 Ago , 2017 6:19 pm
Ubicación: the matrix

Gestión del teclado con la CPCTelera

Mensajepor a13x15 » Dom 27 Ago , 2017 1:35 pm

Hola a todos,
estoy con un programilla, probando la CPCTelera, y no me acaba de gustar como he resuelto el tema del teclado.

Al principio mi código era algo así:

Código: Seleccionar todo

i8 vel_x, vel_y;
u8 debug_show;

void game_read_keys(void) {
cpct_scanKeyboard_f();

if (!cpct_isAnyKeyPressed_f()) {
return;
}

if (cpct_isKeyPressed(Key_D)) {
debug_show = !debug_show;
}

if (cpct_isKeyPressed(Key_J) && !vel_x) { // izquierda
vel_x = -1;
vel_y = 0;
return;
}
// lo mismo para el resto de teclas de dirección
}
Esta función es llamada en cada iteración del bucle del juego. El problema con ella es que la tecla D no es para nada fiable. El valor de debug_show dependerá del número de iteraciones (par o impar) del bucle de juego durante el periodo en que se ha mantenido pulsada.

Por el momento lo he "resuelto" añadiendo un "contador" que se incrementa en cada interrupción. La función de lectura de teclado solo es llamada cada N interrupciones. Funciona, mas o menos, pero no me acaba de convencer.

Otra forma que se me ha ocurrido consiste en detectar los keydown/keyup y ejecutar el cambio de estado como respuesta a los keyup. Algo como:

Código: Seleccionar todo

u8 debug_show;

void leer_teclado(void) {
static u8 D_sigue_pulsada = 0;
static u8 D_keyup = 0;

if (cpct_isKeyPressed(Key_D)) {
D_sigue_pulsada = 1;
} else { // no pulsada
if (D_sigue_pulsada) {
D_sigue_pulsada = 0;
D_keyup = 1;
}
}
if (D_keyup) {
debug_show = !debug_show;
D_keyup = 0;
}
}

void juego(void) {
debug_show = 0;

while (1) {
leer_teclado();
if (debug_show) {
mostrar_info();
}
}
No lo he probado (se me ha ocurrido mientra redactaba el mensaje). Si no me he equivocado mucho, parece mas fiable y supongo que se podria adaptar para reaccionar en el keydown en lugar del keyup. De todas formas me parece rebuscado y pienso que tiene que haber una solución mas simple trasteando con el hardware del CPC.

Pues eso ¿que técnicas utilizais para gestionar la lectura del teclado durante el juego?


Grácias por adelantado!!

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor ronaldo » Lun 28 Ago , 2017 12:19 am

Hola @a13x15,

Lo que te sucede es muy normal. Pasa sobre todo cuando tienes programas en estado inicial, que no tienen muchas cosas que hacer en cada ciclo de ejecución y van muy rápido. Si puedes leer el teclado 50 veces por segundo, es normal que la simple detección de tecla pulsada no te sea suficiente para tareas de interruptor como el modo debug. Nadie de nosotros está preparado para pulsar una tecla 1/50 de segundo y soltar rápidamente.

Personalmente, salvo que tengas más motivos que el debug, no implementaría un keyDown, keyUp para juegos. Precisamente es lo contrario a lo que sueles querer en un juego: quieres que se detecte sólo el hecho de que la tecla está pulsada, y que sea lo más rápido posible para que el control sea lo más suave posible. Para algo como el debug, sobra con que añadas un flag que impida nuevos cambios por pulsación. Sería una especie de keyDown muy simple. En este caso, creo que mejor si es más simple.

Código: Seleccionar todo

void game_read_keys(void) {
cpct_scanKeyboard_f();
if (!cpct_isAnyKeyPressed_f()) return;

if (cpct_isKeyPressed(Key_D))
if (!D_pressed) {
debug_show = !debug_show;
D_pressed = 1;
}
} else
D_pressed = 0;

//.....
}
Para un caso como este, como digo, creo que mejor mantenerse así de simple. Si te hicieran falta más cosas parecidas, pensaría en usar los 8 bits de una única variable como flags (en vez de usar bytes enteros como booleanos) y crear una función para aplicarle este cuento repetidamente a todas las teclas que tocan. Imagino que no te hará falta una cosa así, porque en la mayoría de los casos necesitarás sólo las pulsaciones.

Suerte en lo que estés haciendo!

Avatar de Usuario
a13x15
Lechoncillo
Lechoncillo
Mensajes: 15
Registrado: Mié 23 Ago , 2017 6:19 pm
Ubicación: the matrix

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor a13x15 » Lun 28 Ago , 2017 5:02 pm

Antes de nada muchas gracias por responder y por crear y compartir la CPCTelera =D>

Por lo que dices entiendo que no hay nada en el hardware que ayude a detectar las pulsaciones, hay que utilizar polling sí o sí.

Al final me vine arriba y generalicé lo del keyup utilizando un mapa de bits (código). Leyendo tu respuesta me doy cuenta de que tengo que cambiar el chip, con las limitaciones del CPC a veces una solución específica más sencilla puede ser preferible ](*,) . La función de lectura de los controles del juego está aquí y la de debug aquí. Para los controles utilizo escaneo directo y para el debug eventos (por llamarlo de alguna forma). Después del cambio la respuesta del juego a las teclas de debug ha mejorado muchísimo, es fiable \:D/ .

Otra duda que tengo es la forma de organizar el bucle de juego en relación al tiempo. Lo que tengo ahora es algo así:

Código: Seleccionar todo

// reloj es un contador que se incrementa en cada interrupción.
bucle infinito:
leer_teclado() // actualiza globales con los comandos
si reloj >= retardo:
actualizar estado de los elementos en función de los comandos
si game_over salir del bucle
reiniciar reloj
esperar VSYNC
reproducir música
pintar pantalla
Funciona pero me queda la sensación de que no es la forma de hacerlo.

Sé que son preguntas muy tontas pero hasta que le coja un poco el tranquillo voy algo perdido.


Saludos!!

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor ronaldo » Lun 28 Ago , 2017 5:37 pm

Antes de nada muchas gracias por responder y por crear y compartir la CPCTelera =D>

Por lo que dices entiendo que no hay nada en el hardware que ayude a detectar las pulsaciones, hay que utilizar polling sí o sí.
No hay de qué, faltaría más.

Al nivel hardware más bajo, todos los teclados son así, no sólo el del CPC. KeyUp y KeyDown siempre es una capa por encima del hardware, aunque venga implementada en firmware.
Otra duda que tengo es la forma de organizar el bucle de juego en relación al tiempo. Lo que tengo ahora es algo así:
No veo que tiene de malo ese esquema. Depende de lo que quieras conseguir.

En todo caso, si usas interrupciones, lo lógico es que la música se reproduzca en una de ellas. El dibujado normalmente quieres que se haga lo primero de todo después de un VSYNC, para tener más tiempo antes de que te pille el raster, salvo que uses doble buffer.

Otro consejo interesante: Manten el código de tus funciones lo más corto y minimalista posible. El compilador de C produce mejor código con funciones cortas, donde puede manejar todo en registros, que con funciones largas donde pasa a trajinar entre registros y memoria.

Avatar de Usuario
a13x15
Lechoncillo
Lechoncillo
Mensajes: 15
Registrado: Mié 23 Ago , 2017 6:19 pm
Ubicación: the matrix

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor a13x15 » Lun 28 Ago , 2017 8:22 pm

Al nivel hardware más bajo, todos los teclados son así, no sólo el del CPC. KeyUp y KeyDown siempre es una capa por encima del hardware, aunque venga implementada en firmware.
:-k tengo mucho que aprender.
No veo que tiene de malo ese esquema. Depende de lo que quieras conseguir.
No, si funcionar funciona, de forma bastante digna, y en última instancia es lo que importa. Es el moverme por terreno desconocido lo que hace que me cuestione las soluciones que elijo.
En todo caso, si usas interrupciones, lo lógico es que la música se reproduzca en una de ellas. El dibujado normalmente quieres que se haga lo primero de todo después de un VSYNC, para tener más tiempo antes de que te pille el raster, salvo que uses doble buffer.
#-o lo dicho, mucho que aprender.

En algún momento lo pensé pero como no tengo muy claro como van y en todas partes leía que la rutina de interrupción sea rápida, pues será mas rápida si no le meto el musicPlay y así quedo la cosa. Es lo que tiene hacer las cosas sin acabar de entenderlas. Por suerte la ignorancia tiene cura :)
Otro consejo interesante: Manten el código de tus funciones lo más corto y minimalista posible. El compilador de C produce mejor código con funciones cortas, donde puede manejar todo en registros, que con funciones largas donde pasa a trajinar entre registros y memoria.
Tomo nota. Tengo pendiente sacar la lógica del juego fuera de "main.c", aprovecharé para intentar reestructurar el código en partes mas manejables.


Saludos!!

Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Mié 18 Oct , 2017 11:23 am

Por esto se recomienda utilizar una de 2 posibles opciones:
  1. Definir las variables como constantes globales y luego modificarlas a nuestro gusto, saltándonos los warnings del compilador. Al ser definidas como constantes, el compilador asume que pueden estar en ROM y no genera las 2 copias antes mencionadas, pero en nuestro caso práctico están en RAM, por lo que podemos modificarlas con un poco de maña.
¿Esto sigue igual en la última versión de cpctelera (que ha actualizado el compilador)?
Visita mi canal de YouTube http://www.youtube.com/c/jgonza

Avatar de Usuario
ronaldo
Forum Addict
Forum Addict
Mensajes: 358
Registrado: Sab 14 Sep , 2013 9:31 pm
Ubicación: Alicante
Contactar:

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor ronaldo » Mié 18 Oct , 2017 11:30 am

¿Esto sigue igual en la última versión de cpctelera (que ha actualizado el compilador)?
Sí, exactamente igual y no es esperable que cambie. SDCC está diseñado para entornos embebidos, por lo que asume que se ejecuta desde ROM. Por eso, las variables globales para él ocupan 2 espacios de memoria + código. 1 espacio en RAM (la variable) y otro en ROM (el valor inicial) más el código que copia de uno a otro.

De todas formas, creo que definirlas a mano con ensamblador inline también es un buen método, si sabes hacerlo. Para los casos simples se pueden crear marcos que lo automaticen y simplifiquen. Para estructuras de datos ya sería bastante más complejo y toca saber cómo va a mano.

Esto mientras uses C. En ensamblador no hay problema.

Avatar de Usuario
jgonza
Keeper of The Forum
Keeper of The Forum
Mensajes: 962
Registrado: Mié 04 Abr , 2007 9:21 pm
Ubicación: Alboraya (Valencia)

Re: CPCtelera, desarrollar juegos para Amstrad de forma sencilla

Mensajepor jgonza » Mié 18 Oct , 2017 3:26 pm

A ver si termino de aclararme, pongamos por caso los siguientes ejemplos y lo que sucedería exactamente:

a) variable global con inicialización (int x = 100;)

Resultado:
- el espacio de almacenamiento en memoria relacionado con la variable x se duplica
- el valor 100 no se ha guardado dentro de x como valor inicial

b) variable global sin inicialización (int x;) y posterior inicialización, por ejemplo, dentro de main (x = 100;)

Resultado:
- el espacio de almacenamiento en memoria relacionado con la variable x se duplica
- x contiene un 0 por defecto inicialmente o posiblemente **lo que ya hubiera en la memoria**
- x contiene el valor de 100 desde el momento de la asignación

c) variable global con inicialización como constante global (const int x = 100;)
. el espacio de almacenamiento en memoria es el correcto
- x contiene correctamente el valor de 100
- no se puede modificar x alegremente (no compila), hay que hacerlo "con algo de maña" como he leído por algún post

d) variable global sin inicialización como constante global (const int x;)
. el espacio de almacenamiento en memoria es el correcto
- x contiene un 0 por defecto inicialmente o posiblemente **lo que ya hubiera en la memoria**
- no se puede modificar x alegremente (no compila), hay que hacerlo "con algo de maña" como he leído por algún post

Confimar o desmentir lo anterior, porfa <rX
Visita mi canal de YouTube http://www.youtube.com/c/jgonza


¿Quién está conectado?

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


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic