Tv-out Enable Detection


JyCet

Member
Joined
Feb 23, 2004
Messages
469
Age
118
Location
France
Website
Visit site
Hi all,
I've read from this board that to have a good tv-out scaling we need to change the screen surface resolution with SDL.
Now I search how to detect if the tv out is activate or not to initalize a correct size surface
CODE
unsigned short *gp2x_memregs;

if((gp2x_memregs[0x2800>>1]&0x100)) //TVout detect
ecran = SDL_SetVideoMode(360, 288, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
else ecran = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);


I dont know why but this code doesnt work.

I've found another pb with TV-out, when it's enable SDL_Flip(ecran); doesnt synch the video @ 60Hz, so there're a lot of flickering and the speed is to fast :(

Any suggestion or help are welcome :)
Thanks.
 
You're missing some code. gp2x_memregs needs to be mmap'd to the area of memory you're working with (don't have the code around at the moment, but you should be able to find it easy enough). You'll also want to check if it's PAL or NTSC that's enabled.

As for the flickering, I've seen it happen with hardware surfaces but I've never had time to look into why.

I'm also trying to get the true 320x240 tv game modes working (for open2x) so you don't have to do any checks like this, but so far they're refusing to work.
 
Thanks woogal now screen detection work :)
Here correct code:
CODE
#include <fcntl.h>
#include <sys/mman.h>

unsigned long gp2x_dev;
unsigned short *gp2x_memregs;
...
if(!gp2x_dev) gp2x_dev = open("/dev/mem", O_RDWR);
gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev, 0xc0000000);
// TV OUT
if((gp2x_memregs[0x2800>>1]&0x100)){
if (gp2x_memregs[0x2818>>1] == 287) //PAL
ecran = SDL_SetVideoMode(360, 288, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
else if (gp2x_memregs[0x2818>>1] == 239) //NTSC
ecran = SDL_SetVideoMode(360, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 1;
}else{
//LCD
ecran = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 0;
}
...



I use flag_TV for a manual frame limiter in TV mode. It's not perfect but it work better than nothing :)
 
Jycet,
I tried using your tv out code, but my dev C++ complain about :
sys/mman.h: No such file or directory.

Do you need to add a directory in your project options ?
( I'm using the "official" GP2X dev kit)
 
kouky said:
Jycet,
I tried using your tv out code, but my dev C++ complain about :
sys/mman.h: No such file or directory.

Do you need to add a directory in your project options ?
( I'm using the "official" GP2X dev kit)
Only works for the GP2x compile target, not for the Windows compile target.
 
Last edited by a moderator:
kouky said:
Jycet,
I tried using your tv out code, but my dev C++ complain about :
sys/mman.h: No such file or directory.

Do you need to add a directory in your project options ?
( I'm using the "official" GP2X dev kit)
Yes this is only for GP2X so i suggess you to add #ifdef ....

And in TV-OUT mode the VSYNC doesn't work so you'll need to code a manual frame limiter. To suppress all flickering , work in a virtual surface screen and when your virtual surface screen is ready copy it in the real surface screen (TV surface in fact)
 
Last edited by a moderator:
JyCet,

I can't make your code to work :/

I'm triying to enable TV out, and then adjust the size of the surface, but the program allways crash (comes back to the menu, but i TV mode) when i draw something on the surface.

my code:
CODE

unsigned long gp2x_dev;
unsigned short *gp2x_memregs;


handle=open("/dev/cx25874",O_RDWR);ioctl(handle, _IOW('v', 0x02, unsigned char), 4);// tv out in PAL mode


if(!gp2x_dev) gp2x_dev = open("/dev/mem", O_RDWR);
gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev, 0xc0000000);
// TV OUT
if((gp2x_memregs[0x2800>>1]&0x100)){
if (gp2x_memregs[0x2818>>1] == 287) //PAL
screen[0] = SDL_SetVideoMode(360, 288, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
else if (gp2x_memregs[0x2818>>1] == 239) //NTSC
screen[0] = SDL_SetVideoMode(360, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 1;
}else{
//LCD
screen[0] = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 0;
}

Rect.y=20;
Rect.w=280;
Rect.h=200;
Rect.x=20;
SDL_FillRect(screen[0],&Rect,0xFFF);
SDL_UpdateRect(screen[0],0,0,0,0);


what's wrong ?
 
kouky said:
JyCet,

I can't make your code to work :/

I'm triying to enable TV out, and then adjust the size of the surface, but the program allways crash (comes back to the menu, but i TV mode) when i draw something on the surface.

my code:
CODE

unsigned long gp2x_dev;
unsigned short *gp2x_memregs;
handle=open("/dev/cx25874",O_RDWR);ioctl(handle, _IOW('v', 0x02, unsigned char), 4);// tv out in PAL mode


if(!gp2x_dev) gp2x_dev = open("/dev/mem", O_RDWR);
gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev, 0xc0000000);
// TV OUT
if((gp2x_memregs[0x2800>>1]&0x100)){
if (gp2x_memregs[0x2818>>1] == 287) //PAL
screen[0] = SDL_SetVideoMode(360, 288, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
else if (gp2x_memregs[0x2818>>1] == 239) //NTSC
screen[0] = SDL_SetVideoMode(360, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 1;
}else{
//LCD
screen[0] = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
flag_TV = 0;
}

Rect.y=20;
Rect.w=280;
Rect.h=200;
Rect.x=20;
SDL_FillRect(screen[0],&Rect,0xFFF);
SDL_UpdateRect(screen[0],0,0,0,0);


what's wrong ?


I always used the gp2x menu to turn on/off TV-Out, I dont know if your TVout activation is ok or not, otherwise you can look in source of drill2x xtreme or capex or rage2x for tvout detection and offset example ;)

If you use SDL_DOUBLEBUF flag it's better to use SDL_flip(your_surface); but in tv mode SDL_DOUBLEBUF doesnt work correctly because there s no LCD vsync. You need to add a frame limiter.
:)
 
Last edited by a moderator:
Back
Top