PDA

Ver la versión completa : rayas en el lado derecho de la pantalla



Ruppert51
20/11/2004, 11:44
Hola,
tengo un problema al lanzar este programa muuuy simple en la GP32 :
GameEngine()
{
while(1)
{

GGpRectFill(NULL, &gpDraw[nflip], 0, 0, gpDraw[nflip].buf_w, gpDraw[nflip].buf_h, 0xff);
GpTextOut(NULL, gpDraw[nflip], 50, 50, "HOLA", 114);
GpSurfaceFlip(&gpDraw[nflip++]);
nflip &= 0x01;
}
}

Siempre me salen unas rayas raras en el lado derecho de la pantalla. Quando lo intento en el GeePee32 sale estupendo.
Uso el devkitadv y el Gp32IDE.
Alguien tiene el mismo problema o me puede ayudar???
Gracias

:D

Puck2099
20/11/2004, 12:28
Especifica un poco como son las "rayas raras" porque igual tienes el mismo problema que yo...

¿Es como un temblor de la parte derecha de la pantalla?, ¿con una especie de parpadeos?

Saludos

Ruppert51
20/11/2004, 16:07
exactamente como lo dices.
Lo raro es, que solo me pasa con los programas que me hago.
Si pongo el fondo blanco y encima un rectangulo azul me salen unas rayas blancas en el rectangulo.
Si encima uso GpKeyGet() y aprieto un boton las rayas esas se van un momento mientras que pulso el boton.

Puck2099
20/11/2004, 16:32
Joe, pues estás entonces igual que yo. A mi me pasó eso y me tiré unas cuantas horas cambiando código aquí y allí para intentar arreglar la cosa pero fue en vano...

Al menos como tu programa es muy simple voy a intentar buscar la solución para así extrapolarla a mi juego a ver si podemos arreglar los dos el fallo :)

Saludos

(_=*ZaXeR*=_)
20/11/2004, 17:04
Pero para el ejemplo ese porque meteis las sentencias en un bucle?

Ruppert51
20/11/2004, 17:45
Que quieres decir con eso??
Te refieres al while(1) ??

kmkzk
20/11/2004, 19:34
Escrito originalmente por (_=*ZaXeR*=_)
Pero para el ejemplo ese porque meteis las sentencias en un bucle?

Sin ese bucle, se acabria el programa X)
Se podrian poner las sentecias primero y luego un bucle vacio, pero bueno, con eso no hacemos mucho.

(_=*ZaXeR*=_)
20/11/2004, 20:24
Gracias por la informacion, es que esto de la programacion no es lo mio.

theNestruo
20/11/2004, 20:42
Yo apostaría a que no estais esperando la sincronización vertical (o mejor dicho, la horizontal, en el caso de la GP32), y por eso os salen esas rayas pálidas.

Escrito originalmente por Ruppert51
GpSurfaceFlip(&gpDraw[nflip++]);
Prueba con


GpSurfaceFlip (&gpDraw [++nflip]);

A lo mejor estoy diciendo una tontería (aún no he comenzado a programar para la GP32), pero por probar nada se pierde.

Ruppert51
20/11/2004, 20:56
No, eso tampoco es. Sí lo haces así se vé un chorro de esas rayas.
Pero si alguien teine que saber que es lo estamos haciendo mal:( :(

Ruppert51
21/11/2004, 10:13
Ufff!!
Ayer me tiré todo el dia con el codigo ese, pero sigo sin saber que es lo que esta bien.

BeaR
21/11/2004, 10:26
Habeis preguntado en el canal #gp32dev ???? preguntad ke seguro ke os lo solucionan ;)

Salu2 :musico: :brindis: :musico:

(_=*ZaXeR*=_)
21/11/2004, 13:27
Sigo sin entender el porque quieres meter las sentencias dentro del bucle cuando solo las quieres hacer una vez.

1º El doble buffer suele dar problemas y comederos de cabeza.
2º Los bucles nunca deben ser infinitos, ya se que es un ejemplo, y que se trata de un juego, pero debes acostumbrarte a hacerlo evaluando siempre condiciones logicas, asi conseguiras una programacion mas formal y estricta (igual de efectiva) pero que en otro tipo de programas te puede quitar de problemas.
3º Cuando quieras usar el doble buffer hazlo de la siguiente forma:

#include "gpdef.h"
#include "gpstdlib.h"
#include "gpgraphic.h"
#include "gpmain.h"
#include "gpfont.h"

GPDRAWSURFACE gpDraw[2];

void GpMain(void *arg)
{
int nflip=1;
int i,boton;
int exit=0;

GpLcdSurfaceGet(&gpDraw[0], 0);
GpLcdSurfaceGet(&gpDraw[1], 1);
GpSurfaceSet(&gpDraw[0]);
for (i=0;i<=2;i++) GpRectFill(NULL, &gpDraw[i], 0, 0, gpDraw[i].buf_w, gpDraw[i].buf_h, 0xFF);
GpLcdEnable();
while (!exit)
{
GpTextOut(NULL, &gpDraw[nflip], 240,227, "Hola", 0x07);
boton= GpKeyGet();
if (boton==(GPC_VK_FA) exit=1;
GpSurfaceFlip(&gpDraw[nflip++]);
nflip &= 0x01;
}
}

Para tu ejemplo prueba con esto, espero que te solucione el problema, confio que si.

#include "gpdef.h"
#include "gpstdlib.h"
#include "gpgraphic.h"
#include "gpmain.h"
#include "gpfont.h"

GPDRAWSURFACE gpDraw;

void GpMain(void *arg)
{
int i;
int exit=0;
int boton;

i = GpLcdSurfaceGet(&gpDraw, 0);
GpRectFill(NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0xff);
GpSurfaceSet(&gpDraw);
if ( !(GPC_LCD_ON_BIT & GpLcdStatusGet()) ) GpLcdEnable();
GpTextOut(NULL, gpDraw, 50, 50, "HOLA", 0x07);
while(!exit)
{
boton= GpKeyGet();
if (boton==(GPC_VK_FA) exit=1;
}
}

Un saludo y suerte.

Puck2099
21/11/2004, 13:36
(_=*ZaXeR*=_), para la GP32 yo creo que todos los programas deben ir en un bucle infinito porque sino al terminarse el programa, ¿qué hace la consola?


Ruppert51, acabo de compilar tu código y, haciendo algunas correcciones, funciona perfectamente.

No se si lo que has escrito aquí es tu código copiado y pegado o lo has puesto de cabeza, pero de ser el primer caso no creo ni que te compilara.

Aquí tienes tu código modificado para que funcione:



#include <gpdef.h>
#include <gpstdlib.h>
#include <gpgraphic.h>
#include <gpmm.h>
#include <gpstdio.h>
#include "gpmain.h"

#ifndef RANDOM
#define RANDOM 31000
#endif

GPDRAWSURFACE gpDraw[2];

int nflip;


void GpMain(void * arg)
{
GpGraphicModeSet(8, NULL);
GpLcdSurfaceGet( &gpDraw[0], 0);
GpLcdSurfaceGet( &gpDraw[1], 1);
GpSurfaceSet( &gpDraw[1]);
GpLcdEnable();

nflip = 1;

while(1)
{

GpRectFill(NULL, &gpDraw[nflip], 0, 0, gpDraw[nflip].buf_w, gpDraw[nflip].buf_h, 0xff);
GpTextOut(NULL, &gpDraw[nflip], 50, 50, "HOLA", 114);
GpSurfaceFlip(&gpDraw[nflip++]);
nflip &= 0x01;
}
}

Ulward
21/11/2004, 13:42
me imagino q abra escrito el codigo sin un asistente de correccion o lo q sea, al pasarlo al compilador es cuando lo tienes q retocar ...

(_=*ZaXeR*=_)
21/11/2004, 13:43
Escrito originalmente por Puck2099
(_=*ZaXeR*=_), para la GP32 yo creo que todos los programas deben ir en un bucle infinito porque sino al terminarse el programa, ¿qué hace la consola?


No caigas en el error de pensar que lo que yo he puesto no es un bucle infinito, el bucle logicamente es necesario, pensaba que me creias mas inteligente.
Lo que he explicado es que siempre hay que tener el control del flujo del programa, y no usar el while (1) siempre, aunque funcione, porque tambien funciona un while (i<1000) en el que no incrementamos la variable i.

Ruppert51
21/11/2004, 17:02
Puck, lo que habia puesto solo era mi funcion GameEngine.
Yo lo hago tal como lo habia leido en el tutorial de Rico, por eso pensaba que estaba claro que antes de esa funcion GameEngine vendria la funcion Init en GpMain que incluye esto:

void Init()
{
int i;
GpClockSpeedChange(132000000, 0x24001, 2);
nflip = 1;
for(i = 0; i < 2 ; i++)
{
GpLcdSurfaceGet(&gpDraw[i], i);
}
GpSurfaceSet(&gpDraw[0]);
}

Ahora acabo de cambiar el codigo de Puck por el mio y me funciona de maravilla.
Asi que muchas gracias por ayudarme Zaxer y Puck.
Pero de todas formas, no te quejabas del mismo problema Puck???

saludos

ruppert51

Lizardos
22/11/2004, 17:36
Ahora que acabo de implementar el doble buffer en mi juego me ha ocurrido eso mismo, flicker vertical, así que este hilo me ha venido de escándalo.

Esto está sacado del manual del SDK:
GpLcdEnable -> This function activates the video signal toward LCD (call this function after GpSurfaceSet to reduce
flicking).

Saludos, Lizardos.

oankali
26/11/2004, 09:03
El problema viene del cambio de velocidad del procesador.
Lo digo porqué un día empecé investigando el tema ese, y según la velocidad que utilizaba, el refresco de la pantalla fallaba y parpadeaba la parte de la derecha. Y eso sin cambiar una sola línea del código.
Si te fijas Ruppert, Puck no la ha cambiado y funciona correctamente.
Lo que no he provado, pensando en lo que dice Lizardos, es volver a llamar GpLcdEnable() después del cambio de la velocidad del procesador. Habría que probarlo.

theNestruo, en principio no hay que esperar sincronización vertical para evitar parpadeo utilizando doble buffer, ya que lo hace GpSurfaceFlip() automáticamente, por eso a veces algunos programadores se han encontrado que la disminución de velocidad del refresco de la pantalla no era directamente proporcional a la cantidad de sprites en pantalla, sino que va por escalones. O sea que si en un ciclo de refresco consigues meter 10 sprites, si metes 10 sprites o menos el refresco de pantalla será el máximo y a la que le metes 11 sprites, será de la mitad, porque GpSurfaceFlip() esperará otro ciclo más.

Zaxer, el doble buffer funciona super bien, si tienes en cuenta lo que he dicho antes. A mí no me ha dado nunca ningún problema.

Y ahora para todos los que empiezan a programar: ¿porqué teneis tendencia a poner siempre la velocidad del procesador por encima de las necesidades del programa? La velocidad por defecto con el SDK oficial es más que suficiente para la mayoría de los casos. Si no recuerdo mal está en unos 60Mhz.
En mis juegos PuzzleMix, Animings y Pyramids está a 40Mhz. En Pyramids 2 subo la velocidad para ciertos efectos especiales en los menús y luego la vuelvo a dejar como estaba.
Pensad que cuanto menor la velocidad, más duran las baterías.

Oankali.

Ruppert51
26/11/2004, 12:23
Por cierto.
ya que estamos en el tema de cambiarle la velocidad al procesador.
Sé que se cambia con GpClockSpeedChange(132000000, 0x24001, 2),
pero si la quiero poner a 80Mhz por ejemplo, que tengo poner??
Supongo que lo primero tiene que ser 80000000.

saludos
ruppert51

oankali
26/11/2004, 14:55
No es tan sencillo, de echo, aún no he encontrado una buena documentación al respecto.
Aquí adjunto las funciones que utilizo, inspiradas en código de ThunderZ, de Mr Mirko y mio.

(_=*ZaXeR*=_)
28/11/2004, 13:14
El doble buffer si funciona bien, pero cuando me refiero a que da problemas es por el tema de controlar en cual de los dos buffer se esta trabajando, hay veces que dibujas en uno y piensas que lo haces en el otro, depende del codigo claro, de si usas funciones, como era el caso, etc. (lo digo porque a mi me dio algunos problemas hasta que comprendi como funciona y lo que hace, nunca habia programado un juego, solo software de gestion, y algoritmos) Como el ejemplo que ha puesto el compañero era tan sencillo, he supuesto que estaba comenzando a programar, y para hacer un "Hola mundo" el doble buffer no es necesario, lo que puede hacer es que te lies mas.

El tema de la velocidad tienes toda la razon, no se para que todo el mundo pone en su codigo los 133Mhz, lo que se consigue asi es que la gente no se esfuerce en optimizar el codigo para tratar de que funcione a 40Mhz, lo que hace que muchos proyectos nunca se terminen, o se diga que son imposibles. (no olvidemos que nos encontramos en un hardware limitado, no como un pc, y hay que cuidar mucho los recursos que consumimos) Mi estrategia es comenzar en lo minimo 40Mhz optimizar al maximo de lo que puedo, y si me veo forzado, subo un escalon mas 66Mhz, asi sucesivamente, lo malo de esto es que hay que dedicar mucho trabajo y cuando el codigo esta optimizado, tienes que comenzar a plantearte el sustituir algunas instrucciones por otras, lo que implica un conocimiento a bajo nivel de lo que hacen esas instrucciones en codigo maquina, como el sustituir switch por if etc.