Unas dudillas para programar mi "motor grafico"

Czhincksx

Hola. Quería hacer un motor gráfico a base de caracteres de colores en consola de windows (mas tarde linux), pero tengo algunas dudas sobre como hacer algunas cosas. Voya programarlo en C++. Bueno, ahí van las dudas.

-Para cambiar el color de las letras de la consola, el comando es system...

-Para cambiar el color de fondo de la consola. Tanto esto como lo de las letras ya lo hice una vez en un programa pero no recuerdo que comando usé.

-Prefijar un tamaño de consola de x caracteres horizontales y verticales, de forma que el usuario no pueda modificarlo.

Bueno, esas tres cosas serían básicas para el motor. Ahora viene algo más difícil. ¿Cómo puedo leer eventos de teclado? no me gustaría usar ninguna libreria auxiliar como SDL o similares, quisiera que el código fuera todo mio, excepto estas cosas.

El resto del código ya lo tengo todo pensado, ya se como estructurarlo y que necesito, pero sin estas cosas, no puedo ni empezar. Por si alguien tiene curiosidad e resultado final debería ser una pantalla llena con una matriz de caracteres, en la que cada letra la imprimo de un color, por ejemplo v verde y m marron, refrescándola 30 veces por segundo.

Por ejemplo, tengo el mapa, lo cargo en al matriz del tamaño de la pantalla, luego compruebo donde está el personaje y lo sobreescribo encima del mapa en la posición en la que esté, y lo imprimo. Bueno, un saludo y gracias.

sh0ty

Que dificil lo veo... supongo que sabras que para esas cosas es mejor usar la api de windows, no?

Czhincksx

#2 Lo de cambiar los colores es una parida, solo que no recuerdo el comando, y lo del tamaño de la consola supongo que también, lo único complicado sería la lectura de eventos de teclado.

elkaoD

Googlea ANSI color codes.

Para lo de los eventos de teclado, en Linux tienes que poner el terminal en modo... comprometido o algo así se llamaba. Ahora estoy currando, cuando llegue a casa te lo paso.

EDIT: Creo que era modo raw, mira a ver. En Win ni idea de como va.

E

A lo mejor es una estupidez pero... lo de eventos de teclado... con scanf? xD

Aparte pienso que deberias usar alguna libreria, que te van a facilitar mil veces el trabajo.

Czhincksx

#4 OK gracias. Tenía pensado primero hacerlo para windows y luego portearlo a Linux, pero vamos, me da igual el orden XD Si no se como resolover lo de la lectura de eventos, seguramente empezaré haciendo el motor sin más para que calcule una animación con movimientos prefijados y más tarde arreglaré lo de la interacción. Vamos, que básicamente empezaré por el scrolling, un tio saltando, pasando pordelante de algunos objetos y por detras de otros haciendo los movimientos que yo le diga y el resto ya saldrá con el tiempo.

#5 El problema de scanf es que hay que pulsar enter cada vez, y lo que quiero es leer eventos en tiempo real, es decir, si pulsas una tecla, saber que la has pulsado aunque no le des a enter.

r2d2rigo

Ante la duda siempre puedes fusilar la AAlib: http://aa-project.sourceforge.net/aalib/

elkaoD

#6 lo del scanf como te digo se soluciona en raw mode, pero se me ha vuelto a olvidar mirar el código, a ver si a mediodía cuando llegue a casa...

Pero aún así Google es tu amigo, yo lo saqué por Google sin problema.

Czhincksx

#8 OK gracias, en cuanto me despeje lo miro.

elkaoD

Para ayudarte te aclaro un par de cosas

El modo raw lo que hace es tratar las pulsaciones de teclas una a una. En el programa es un bucle que va viendo si se ha pulsado una tecla y te la saca en una variable. Es un poco más lioso que esto pero viendo código de ejemplo se saca fácil.

La pulsaciones de los cursores te las escapa con dos bytes, así que lo que yo hacía era chequear si el primer byte era... creo que 0e0h era el que precedía, y ya actuaba en consecuencia al segundo byte. Pude hacer que se moviera el curso arriba, abajo, izquierda, derecha... vamos, como un procesador de textos.

Luego no se te olvidé quitar el modo crudo porque la terminal se vuelve gilipollas xD

Czhincksx

Ok muchas gracias. Esta tarde empiezo. Lo tomaré con calma, a ver que sale XD

#7 Quiero usar la menor cantidad de código ageno para aprender, aunque me quede algo muy cutre XD

elkaoD

Esto lo he sacado de un cliente/servidor de Mus que hice hace tiempo y dejé un poco a medias. Funcionaba, pero faltaba pulirlo. Ahora que lo veo no sé por qué no usé un case.

Este trozo de código es para una pequeña linea de comandos del cliente.

Lo de charswritten y charswriting lo hice para poder mover el cursor a izquierda y derecha y tal, pero lo dejé a medias y está sin implementar. Aún así si lo quieres solo para pasar los eventos por el motor, no lo necesitas para nada xD

/* Al principio del programa: */
char bufcomm[1024]; // Buffer of what's written
int charsWritten = 0; // How many chars did the user write ?
int charsWriting = 0; // Which char is the user writing to ?

term_rawmode();

/* En el bucle del main: */
usleep(10000); // We don't want to eat 100% CPU cycles.

if (term_wait4input()) // Wait for input
{
	tempChar = print_getchar();
	if (charsWriting < 1023 && (tempChar > 0x20 || tempChar == ' ')) // I don't like buffer overflows, nor codes, but I love spaces
	{
		bufcomm[charsWriting] = tempChar;
		charsWritten++;
		charsWriting++;
	}
}

/* Al final del programa: */
term_reset();

/*
* print_getchar - print and do a getchar
* Esta función hace el trabajo. El código lo tengo a medias pero es para que cojas el concepto. Sin los printf's y el getchar lo que escribes no hace echo.
*/

int print_getchar(void)
{
	int c;

c = getchar();
if (c == 0xd) // ENTER
{
	bufcomm[charsWritten] = '\0';

	charsWriting = 0;
	charsWritten = 0;
	putchar('\n');

	readCommand(); // Esta función procesalo que tengo en el  buffer y lo procesa, depende de lo que quieras hacer necesitarás algo así o no.
}
else if (c == 0x3) // CTRL+C
	cexit (0);
else if (c == 0x7f) // Backspace
{
	charsWriting--;
	if (charsWriting < 0)
		charsWriting = 0;
	printf("\b \b");
}
// TODO: Cursores
else if ((c >= 0) && (c < 0x20))
{
	//printf("0x%x", c);
	printf("^%c", c + '@');
}
else
	putchar(c);
fflush(stdout);

return c;
}

Aún así si quieres hacer lo que creo que quieres hacer, con un getchar() y el terminal en modo raw, te sobra.

Cuidado con los cursores que recuerdo que aquí no lo llegué a implementar por no sé qué historia. Creo recordar que era algo como que c recibía dos valores o algo así... Vamos, lo que te he comentado antes de comprobar si el primer valor es 0e0h. Ya dirás si te da problemas o no xD

Espero que te sirva. Al principio parece una locura cogerlo, pero es fácil, fácil. Me costó mil veces más implementar los sockets (Qué locura la forma de tratarlos, en serio.)

Czhincksx

Muchísimas gracias. Probablemente tarde bastante en tener algo que se pueda enseñar, pero en cuanto lo tenga serás el primero en saberlo.

Gracias, un saludo.

Usuarios habituales

  • Czhincksx
  • elkaoD
  • r2d2rigo
  • Er_jumper
  • sh0ty