Using the TV out in homebrew, whatever cable, full screen
Using the TV out in homebrew, whatever cable, full screen
This is a sample to start the psp slim tv out from homebrew, using whatever cable (d-terminal has not been tested, but i think it has same code as component), and use it in full screen.
You start the sample normally, and then the sample connects to the tv out.
To use it in your code, you just have to replace the call to sceDisplaySetMode with the call to my custom function pspDveMgrSetVideoOut (which calls sceImposeSetVideoOutMode, which at the end calls sceDisplaySetMode), and be aware of the bigger resolution.
The good thing about the tv out, is that the resolution is really bigger (720x503 in composite, 720x480 in component), so it would be cool that video applications are ported to use it ;)
http://www.megaupload.com/?d=QJQ8DEFH
You start the sample normally, and then the sample connects to the tv out.
To use it in your code, you just have to replace the call to sceDisplaySetMode with the call to my custom function pspDveMgrSetVideoOut (which calls sceImposeSetVideoOutMode, which at the end calls sceDisplaySetMode), and be aware of the bigger resolution.
The good thing about the tv out, is that the resolution is really bigger (720x503 in composite, 720x480 in component), so it would be cool that video applications are ported to use it ;)
http://www.megaupload.com/?d=QJQ8DEFH
Last edited by moonlight on Mon Oct 15, 2007 6:22 am, edited 2 times in total.
Thanks,can't wait to test it :D:Djas0nuk wrote:Awesome, thanks DAX :D
Here it is on sendspace, gambiting: http://www.sendspace.com/file/d2ls7q
Now that I think about it, I do have one question: why is composite 503 lines tall? That makes no sense. Composite cannot output any more lines than component. You certainly aren't going to see any more lines. 486 lines is the hard maximum for NTSC compliant composite signals. Perhaps they wanted to give composite a way to do the CC/V-chip embedded in the vertical blank? Nothing else makes any sense for making it more than 480 as well.
I don't know, but those are the values the XMB set without any doubts.J.F. wrote:Now that I think about it, I do have one question: why is composite 503 lines tall? That makes no sense. Composite cannot output any more lines than component. You certainly aren't going to see any more lines. 486 lines is the hard maximum for NTSC compliant composite signals. Perhaps they wanted to give composite a way to do the CC/V-chip embedded in the vertical blank? Nothing else makes any sense for making it more than 480 as well.
For component-interlace, it sets the same resolution that for composite, however I couldn't make that work properly without the screen going odd and moving :S Oh well, who cares about component interlace having progressive.
That's more likely than my guess of trying to allow vertical interval data. I would guess there's more modes there than just the three D_A has mentioned so far.FreePlay wrote:I assume that the video output setup parameters are region-specific? Because this sample seems to be spitting out a PAL signal (i.e. my screen is 'scrolling' in cycles).
This is the table of values i Found in paf.prx:
{ 0, 0, 480, 272, 480, 272, 480, 272, 272, 272 }
{ 0, 0x1d1, 720, 503, 720, 240, 720, 180, 240, 240 }
{ 0, 0x1d2, 720, 480, 720, 480, 720, 360, 480, 480 }
{ 2, 0x1d1, 720, 503, 720, 240, 720, 180, 240, 240 }
The first mode corresponds to normal display. The second to component-interlace, the third to component-progressive, and the fourth to composite. There was no more modes, thus my assuming that d-terminal would be the same as component.
The first value of the array is the one that will end as parameter of sceDve_driver_DEB2F80C.
The next three go to sceImposeSetvideoOutMode, which passes them as they are to sceDisplaySetMode. I don't know what the others params are there for.
FreePlay: I will prepare you later a hooker for the XMB anyways, to see the values it passes in your psp.
Edit: damn, i didn't this on purpose, I didn't know hooker meant bitch ¬¬ I meant a program to hook functions :p
Btw, the XMB used a value of 768 for the bufferwidth in sceDisplaySetFrameBuf, instead of 1024 as in my sample, but anyways I doubt that would change anything, anyways better to use a smaller buffer, my bad aproximating 720 to 1024 instead of to 768 xD
{ 0, 0, 480, 272, 480, 272, 480, 272, 272, 272 }
{ 0, 0x1d1, 720, 503, 720, 240, 720, 180, 240, 240 }
{ 0, 0x1d2, 720, 480, 720, 480, 720, 360, 480, 480 }
{ 2, 0x1d1, 720, 503, 720, 240, 720, 180, 240, 240 }
The first mode corresponds to normal display. The second to component-interlace, the third to component-progressive, and the fourth to composite. There was no more modes, thus my assuming that d-terminal would be the same as component.
The first value of the array is the one that will end as parameter of sceDve_driver_DEB2F80C.
The next three go to sceImposeSetvideoOutMode, which passes them as they are to sceDisplaySetMode. I don't know what the others params are there for.
FreePlay: I will prepare you later a hooker for the XMB anyways, to see the values it passes in your psp.
Edit: damn, i didn't this on purpose, I didn't know hooker meant bitch ¬¬ I meant a program to hook functions :p
Btw, the XMB used a value of 768 for the bufferwidth in sceDisplaySetFrameBuf, instead of 1024 as in my sample, but anyways I doubt that would change anything, anyways better to use a smaller buffer, my bad aproximating 720 to 1024 instead of to 768 xD
Last edited by moonlight on Tue Oct 16, 2007 6:50 am, edited 1 time in total.
Anyways, something odd seems to happen with composite or component-interlace :S
I'm porting the vshmenu to show properly with the new resolution. I'm duplicating the pixels, so the 8x8 font gets converted in 16x16. The code doesn't touch the screen height for anything, however while it displays correctly in component-progressive, it shows odd in composite or interlace, like with some lines and moving a bit, all of these being the XMB the one that setup the video out. The letters also show bigger than in component, when it should be smaller because of the higher screen height :S
Oh well, i guess composite suck, or maybe the Sony implementation, or probably both :D
Btw, i found out that the 16:9 or 4:3 is something purely software, probably done at the highest level layer (probably done by the vsh code). My vshmenu displayed beyond the pseudo-limits in 4:3, in my 16:9 tv.
I'm porting the vshmenu to show properly with the new resolution. I'm duplicating the pixels, so the 8x8 font gets converted in 16x16. The code doesn't touch the screen height for anything, however while it displays correctly in component-progressive, it shows odd in composite or interlace, like with some lines and moving a bit, all of these being the XMB the one that setup the video out. The letters also show bigger than in component, when it should be smaller because of the higher screen height :S
Oh well, i guess composite suck, or maybe the Sony implementation, or probably both :D
Btw, i found out that the 16:9 or 4:3 is something purely software, probably done at the highest level layer (probably done by the vsh code). My vshmenu displayed beyond the pseudo-limits in 4:3, in my 16:9 tv.
Seems the resolution is not exactly 720x503, even if the XMB sets the resolution to it, and sceGetDisplayMode returns 720x503.
Seems like if true resolution of composite and interlace were 720x240.
The following code fills the screen with a random color:
But "lines" appear.
The following code do the same, but lines do not appear:
So it seems the lines are "interlaced". I thought these things would be handled by hardware, but i was wrong, they have to be handled by software. I guess this is the main reason behind sony not being able to implement composite for games. Games really would have to be coded specifically for it.
Seems like if true resolution of composite and interlace were 720x240.
The following code fills the screen with a random color:
Code: Select all
pspDveMgrSetVideoOut(u, displaymode, width, height, 1, 15, 0);
sceDisplaySetFrameBuf(vram, 768, PSP_DISPLAY_PIXEL_FORMAT_8888, 1);
while (1)
{
u32 color = sceKernelUtilsMt19937UInt(&ctx) & 0x00FFFFFF;
for (y = 0; y < 240; y++)
{
for (x = 0; x < 720; x++)
{
vram[(y*768) + x] = color;
}
}
sceDisplayWaitVblankStart();
sceKernelDelayThread(500000);
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_CROSS)
break;
}
The following code do the same, but lines do not appear:
Code: Select all
pspDveMgrSetVideoOut(u, displaymode, width, height, 1, 15, 0);
sceDisplaySetFrameBuf(vram, 768, PSP_DISPLAY_PIXEL_FORMAT_8888, 1);
while (1)
{
u32 color = sceKernelUtilsMt19937UInt(&ctx) & 0x00FFFFFF;
for (y = 0; y < 503; y++)
{
for (x = 0; x < 720; x++)
{
vram[(y*768) + x] = color;
}
}
sceDisplayWaitVblankStart();
sceKernelDelayThread(500000);
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_CROSS)
break;
}
Last edited by moonlight on Tue Oct 16, 2007 2:32 am, edited 1 time in total.
Nice work! The 768 shows the line width needs to be a multiple of 256, not 512. That does help keep the memory down a little for 720x480 mode. Theoretically speaking, I'd expect the composite and component to use the same display with only a flag or something different to tell the PSP to output composite instead of component - but then I didn't write this... crazy's at Sony did. :)
Does the component interlace mode do the same thing, display-wise, as the composite? It looks from your description that they have separate fields for interlace. That would be the REALLY cheap way to do it. Real video uses mods to skip the lines for the other field. :D
Does the component interlace mode do the same thing, display-wise, as the composite? It looks from your description that they have separate fields for interlace. That would be the REALLY cheap way to do it. Real video uses mods to skip the lines for the other field. :D
Yes, component interlace seems to work exactly in same way.J.F. wrote:Does the component interlace mode do the same thing, display-wise, as the composite? It looks from your description that they have separate fields for interlace. That would be the REALLY cheap way to do it. Real video uses mods to skip the lines for the other field. :D
Btw, i did today a test removing the check in the vsh, forcing the resolution in composite to 480x272, and destroying the sceDisplaySetMode function (which made the dve disconnect in composite) to make games work.
The result appart of having said lines, was that the games were terribly slow, even at 333, unplayable :S Doesn't woth to keep those patches in M33.
I modified the debug printf so I could print to the dve display. Component 720x480 progressive gives a 102x60 text display. I printed 60 lines, and on line 30 printed all the way across. Using that, I can see the overscan for this on my HDTV. There's about 1.5 text lines of overscan at the top, one text line at the bottom, 3.5 chars of overscan on the left, and about 2 chars of overscan on the right. So in text coords, I can read clearly from (4,2) to (99,58).
I'll have to try interlace component next.
I'll have to try interlace component next.
503 is probably not the lines you can see. For PAL 8% of 625 lines are used for synchronisation (that is, only 576 lines are visible). I wonder if it is the same case for 503.J.F. wrote:Now that I think about it, I do have one question: why is composite 503 lines tall? That makes no sense. Composite cannot output any more lines than component. You certainly aren't going to see any more lines. 486 lines is the hard maximum for NTSC compliant composite signals. Perhaps they wanted to give composite a way to do the CC/V-chip embedded in the vertical blank? Nothing else makes any sense for making it more than 480 as well.
Last edited by hlide on Tue Oct 16, 2007 5:15 am, edited 1 time in total.
the cables are supossed to require a TV supporting NTSC...hlide wrote:Did you forget PAL ?J.F. wrote:Now that I think about it, I do have one question: why is composite 503 lines tall? That makes no sense. Composite cannot output any more lines than component. You certainly aren't going to see any more lines. 486 lines is the hard maximum for NTSC compliant composite signals. Perhaps they wanted to give composite a way to do the CC/V-chip embedded in the vertical blank? Nothing else makes any sense for making it more than 480 as well.
That's what I've thought - that sony removed the interlaced mode from games,because it's using too much processing power for smooth play.I'm afraid that homebrew will run slowly too,I'm rewriting my game(shoot4fun) to work with this,and I will see how fast is it when I get my cable.moonlight wrote:Btw, i did today a test removing the check in the vsh, forcing the resolution in composite to 480x272, and destroying the sceDisplaySetMode function (which made the dve disconnect in composite) to make games work.J.F. wrote:Does the component interlace mode do the same thing, display-wise, as the composite? It looks from your description that they have separate fields for interlace. That would be the REALLY cheap way to do it. Real video uses mods to skip the lines for the other field. :D
The result appart of having said lines, was that the games were terribly slow, even at 333, unplayable :S Doesn't woth to keep those patches in M33.
You'll have to modify the code more for it not to show the lines.J.F. wrote:I modified the debug printf so I could print to the dve display. Component 720x480 progressive gives a 102x60 text display. I printed 60 lines, and on line 30 printed all the way across. Using that, I can see the overscan for this on my HDTV. There's about 1.5 text lines of overscan at the top, one text line at the bottom, 3.5 chars of overscan on the left, and about 2 chars of overscan on the right. So in text coords, I can read clearly from (4,2) to (99,58).
I'll have to try interlace component next.
If it is usefull for you, the following code paints a part of the screen of a color without lines:
Code: Select all
for (y = 0; y < 64; y++)
{
for (x = 0; x < 720; x++)
{
vram[(y*768) + x] = color;
vram[(y+262)*768 + x] = color;
}
}
Last edited by moonlight on Tue Oct 16, 2007 5:21 am, edited 1 time in total.
And it is. I done figgered it out! They were even more lazy than you can imagine. The interlaced modes ARE NTSC. The screen buffer in those modes is laid out this way:moonlight wrote:the cables are supossed to require a TV supporting NTSC...hlide wrote:Did you forget PAL ?J.F. wrote:Now that I think about it, I do have one question: why is composite 503 lines tall? That makes no sense. Composite cannot output any more lines than component. You certainly aren't going to see any more lines. 486 lines is the hard maximum for NTSC compliant composite signals. Perhaps they wanted to give composite a way to do the CC/V-chip embedded in the vertical blank? Nothing else makes any sense for making it more than 480 as well.
240 lines of even field
22 lines of nothing
240 lines of odd field
1 line of nothing
I was playing around with the printf some more to figure this out. Half the lines go at the vram base, and half go at vram + 262 * line_width, and only 240 of those lines in the field display anything. So the interlaced modes ARE the same as the progressive mode - 720x480. It's just laid out in an odd manner. 240+22 = 262 = one field is pretty obvious. That one extra line must be the one that's split in half to make the display interlaced.
The overscan on my HDTV in interlaced mode is a little different than in progressive, but pretty close to the same amount. Here's the altered sc_printf.c file I include with the dve sample:
Code: Select all
/*
* PSP Software Development Kit - http://www.pspdev.org
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* scr_printf.c - Debug screen functions.
*
* Copyright (c) 2005 Marcus R. Brown <[email protected]>
* Copyright (c) 2005 James Forshaw <[email protected]>
* Copyright (c) 2005 John Kelley <[email protected]>
*
* $Id: scr_printf.c 2319 2007-09-30 15:58:31Z tyranid $
*/
#include <stdio.h>
#include <psptypes.h>
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspsysclib.h>
#include <pspge.h>
#include <stdarg.h>
#include <pspdebug.h>
#include <string.h>
/* baseado nas libs do Duke... */
void _pspDveScreenClearLine( int Y);
void pspDveScreenInit(int mode);
void pspDveScreenInitEx(void *vram_base, int mode, int setup);
void pspDveScreenPrintf(const char *fmt, ...) __attribute__((format(printf,1,2)));
void pspDveScreenKprintf(const char *format, ...) __attribute__((format(printf,1,2)));
void pspDveScreenEnableBackColor(int enable);
void pspDveScreenSetBackColor(u32 color);
void pspDveScreenSetTextColor(u32 color);
void pspDveScreenSetColorMode(int mode);
void pspDveScreenPutChar(int x, int y, u32 color, u8 ch);
void pspDveScreenSetXY(int x, int y);
void pspDveScreenSetOffset(int offset);
void pspDveScreenSetBase(u32* base);
int pspDveScreenGetX(void);
int pspDveScreenGetY(void);
void pspDveScreenClear(void);
int pspDveScreenPrintData(const char *buff, int size);
int pspDveScreenPuts(const char *str);
static int PSP_FIELD_OFFSET = 262;
static int PSP_SCREEN_HEIGHT = 480;
static int PSP_SCREEN_WIDTH = 720;
static int PSP_LINE_SIZE = 768;
static int X = 0, Y = 0;
static int MX=102, MY=60;
static u32 bg_col = 0, fg_col = 0xFFFFFFFF;
static int bg_enable = 1;
static void* g_vram_base = (u32 *) 0x04000000;
static int g_vram_offset = 0;
static int g_vram_mode = PSP_DISPLAY_PIXEL_FORMAT_8888;
static int init = 0;
static u16 convert_8888_to_565(u32 color)
{
int r, g, b;
b = (color >> 19) & 0x1F;
g = (color >> 10) & 0x3F;
r = (color >> 3) & 0x1F;
return r | (g << 5) | (b << 11);
}
static u16 convert_8888_to_5551(u32 color)
{
int r, g, b, a;
a = (color >> 24) ? 0x8000 : 0;
b = (color >> 19) & 0x1F;
g = (color >> 11) & 0x1F;
r = (color >> 3) & 0x1F;
return a | r | (g << 5) | (b << 10);
}
static u16 convert_8888_to_4444(u32 color)
{
int r, g, b, a;
a = (color >> 28) & 0xF;
b = (color >> 20) & 0xF;
g = (color >> 12) & 0xF;
r = (color >> 4) & 0xF;
return (a << 12) | r | (g << 4) | (b << 8);
}
static void clear_screen_16(u16 color)
{
int x;
u16 *vram = g_vram_base;
vram += (g_vram_offset >> 1);
for(x = 0; x < (PSP_LINE_SIZE * PSP_SCREEN_HEIGHT); x++)
{
*vram++ = color;
}
}
static void clear_screen_32(u32 color)
{
int x;
u32 *vram = g_vram_base;
vram += (g_vram_offset>>2);
for(x = 0; x < (PSP_LINE_SIZE * PSP_SCREEN_HEIGHT); x++)
{
*vram++ = color;
}
}
static void clear_screen(u32 color)
{
if(g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888)
{
clear_screen_32(color);
}
else
{
u16 c = 0;
switch(g_vram_mode)
{
case PSP_DISPLAY_PIXEL_FORMAT_565:
c = convert_8888_to_565(color);
break;
case PSP_DISPLAY_PIXEL_FORMAT_5551:
c = convert_8888_to_5551(color);
break;
case PSP_DISPLAY_PIXEL_FORMAT_4444:
c = convert_8888_to_4444(color);
break;
};
clear_screen_16(c);
}
}
void pspDveScreenInitEx(void *vram_base, int mode, int setup)
{
switch(mode)
{
case PSP_DISPLAY_PIXEL_FORMAT_565:
case PSP_DISPLAY_PIXEL_FORMAT_5551:
case PSP_DISPLAY_PIXEL_FORMAT_4444:
case PSP_DISPLAY_PIXEL_FORMAT_8888:
break;
default:
mode = PSP_DISPLAY_PIXEL_FORMAT_8888;
};
X = Y = 0;
/* Place vram in uncached memory */
if(vram_base == NULL)
{
vram_base = (void*) (0x40000000 | (u32) sceGeEdramGetAddr());
}
g_vram_base = vram_base;
g_vram_offset = 0;
g_vram_mode = mode;
if(setup)
{
switch (setup & 0x7f)
{
case 0:
// composite
pspDveMgrSetVideoOut(2, 0x1d1, 720, 503, 1, 15, 0);
PSP_SCREEN_HEIGHT = 503;
break;
case 1:
// component progressive
pspDveMgrSetVideoOut(0, 0x1d2, 720, 480, 1, 15, 0);
PSP_SCREEN_HEIGHT = 480;
break;
case 2:
// component interlace
pspDveMgrSetVideoOut(0, 0x1d1, 720, 503, 1, 15, 0);
PSP_SCREEN_HEIGHT = 503;
break;
}
sceDisplaySetFrameBuf((void *) g_vram_base, PSP_LINE_SIZE, mode, 1);
}
clear_screen(bg_col);
init = 1;
}
void pspDveScreenInit(int vmode)
{
X = Y = 0;
pspDveScreenInitEx(NULL, PSP_DISPLAY_PIXEL_FORMAT_8888, vmode|0x80);
}
void pspDveScreenEnableBackColor(int enable)
{
bg_enable = enable;
}
void pspDveScreenSetBackColor(u32 colour)
{
bg_col = colour;
}
void pspDveScreenSetTextColor(u32 colour)
{
fg_col = colour;
}
void pspDveScreenSetColorMode(int mode)
{
switch(mode)
{
case PSP_DISPLAY_PIXEL_FORMAT_565:
case PSP_DISPLAY_PIXEL_FORMAT_5551:
case PSP_DISPLAY_PIXEL_FORMAT_4444:
case PSP_DISPLAY_PIXEL_FORMAT_8888:
break;
default:
mode = PSP_DISPLAY_PIXEL_FORMAT_8888;
};
g_vram_mode = mode;
}
int pspDveScreenGetX()
{
return X;
}
int pspDveScreenGetY()
{
return Y;
}
void pspDveScreenClear()
{
int y;
if(!init)
{
return;
}
for(y=0;y<MY;y++)
{
_pspDveScreenClearLine(y);
}
pspDveScreenSetXY(0,0);
clear_screen(bg_col);
}
void pspDveScreenSetXY(int x, int y)
{
if( x<MX && x>=0 ) X=x;
if( y<MY && y>=0 ) Y=y;
}
void pspDveScreenSetOffset(int offset)
{
g_vram_offset = offset;
}
void pspDveScreenSetBase(u32* base)
{
g_vram_base = base;
}
extern u8 msx[];
static void debug_put_char_32(int x, int y, u32 color, u32 bgc, u8 ch)
{
int i,j, l;
u8 *font;
u32 *vram_ptr;
u32 *vram1;
u32 *vram2;
if(!init)
{
return;
}
if (PSP_SCREEN_HEIGHT == 480)
{
vram1 = g_vram_base;
vram1 += (g_vram_offset >> 2) + x;
vram1 += y * PSP_LINE_SIZE;
font = &msx[ (int)ch * 8];
for (i=l=0; i < 8; i++, l+= 8, font++)
{
vram_ptr = vram1;
for (j=0; j < 8; j++)
{
if ((*font & (128 >> j)))
*vram_ptr = color;
else if(bg_enable)
*vram_ptr = bgc;
vram_ptr++;
}
vram1 += PSP_LINE_SIZE;
}
}
else
{
vram1 = g_vram_base;
vram1 += (g_vram_offset >> 3) + x;
vram1 += (y>>1) * PSP_LINE_SIZE;
vram2 = vram1;
vram2 += PSP_FIELD_OFFSET * PSP_LINE_SIZE;
font = &msx[ (int)ch * 8];
for (i=l=0; i < 8; i++, l+= 8, font++)
{
vram_ptr = (i & 1) ? vram1 : vram2;
for (j=0; j < 8; j++)
{
if ((*font & (128 >> j)))
*vram_ptr = color;
else if(bg_enable)
*vram_ptr = bgc;
vram_ptr++;
}
if (i & 1)
vram1 += PSP_LINE_SIZE;
else
vram2 += PSP_LINE_SIZE;
}
}
}
static void debug_put_char_16(int x, int y, u16 color, u16 bgc, u8 ch)
{
int i,j, l;
u8 *font;
u16 *vram_ptr;
u16 *vram1;
u16 *vram2;
if(!init)
{
return;
}
if (PSP_SCREEN_HEIGHT == 480)
{
vram1 = g_vram_base;
vram1 += (g_vram_offset >> 1) + x;
vram1 += y * PSP_LINE_SIZE;
font = &msx[ (int)ch * 8];
for (i=l=0; i < 8; i++, l+= 8, font++)
{
vram_ptr = vram1;
for (j=0; j < 8; j++)
{
if ((*font & (128 >> j)))
*vram_ptr = color;
else if(bg_enable)
*vram_ptr = bgc;
vram_ptr++;
}
vram1 += PSP_LINE_SIZE;
}
}
else
{
vram1 = g_vram_base;
vram1 += (g_vram_offset >> 1) + x;
vram1 += (y>>1) * PSP_LINE_SIZE;
vram2 = vram1;
vram2 += PSP_FIELD_OFFSET * PSP_LINE_SIZE;
font = &msx[ (int)ch * 8];
for (i=l=0; i < 8; i++, l+= 8, font++)
{
vram_ptr = (i & 1) ? vram1 : vram2;
for (j=0; j < 8; j++)
{
if ((*font & (128 >> j)))
*vram_ptr = color;
else if(bg_enable)
*vram_ptr = bgc;
vram_ptr++;
}
if (i & 1)
vram1 += PSP_LINE_SIZE;
else
vram2 += PSP_LINE_SIZE;
}
}
}
void
pspDveScreenPutChar( int x, int y, u32 color, u8 ch)
{
if(g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888)
{
debug_put_char_32(x, y, color, bg_col, ch);
}
else
{
u16 c = 0;
u16 b = 0;
switch(g_vram_mode)
{
case PSP_DISPLAY_PIXEL_FORMAT_565:
c = convert_8888_to_565(color);
b = convert_8888_to_565(bg_col);
break;
case PSP_DISPLAY_PIXEL_FORMAT_5551:
c = convert_8888_to_5551(color);
b = convert_8888_to_5551(bg_col);
break;
case PSP_DISPLAY_PIXEL_FORMAT_4444:
c = convert_8888_to_4444(color);
b = convert_8888_to_4444(bg_col);
break;
};
debug_put_char_16(x, y, c, b, ch);
}
}
void _pspDveScreenClearLine( int Y)
{
int i;
if(bg_enable)
{
for (i=0; i < MX; i++)
{
pspDveScreenPutChar( i*7 , Y * 8, bg_col, 219);
}
}
}
/* Print non-nul terminated strings */
int pspDveScreenPrintData(const char *buff, int size)
{
int i;
int j;
char c;
if(!init)
{
return 0;
}
for (i = 0; i < size; i++)
{
c = buff[i];
switch (c)
{
case '\n':
X = 0;
Y ++;
if (Y == MY)
Y = 0;
_pspDveScreenClearLine(Y);
break;
case '\t':
for (j = 0; j < 5; j++) {
pspDveScreenPutChar( X*7 , Y * 8, fg_col, ' ');
X++;
}
break;
default:
pspDveScreenPutChar( X*7 , Y * 8, fg_col, c);
X++;
if (X == MX)
{
X = 0;
Y++;
if (Y == MY)
Y = 0;
_pspDveScreenClearLine(Y);
}
}
}
return i;
}
int pspDveScreenPuts(const char *str)
{
return pspDveScreenPrintData(str, strlen(str));
}
void pspDveScreenPrintf(const char *format, ...)
{
va_list opt;
char buff[2048];
int bufsz;
va_start(opt, format);
bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
(void) pspDveScreenPrintData(buff, bufsz);
}
Code: Select all
pspDveScreenInit(2);
pspDveScreenClear();
for (i = 0; i < (480/8); i++)
{
if (i != 30)
pspDveScreenPrintf(" Line #%d\n", i);
else
for (j = 0; j < (720/7); j++)
pspDveScreenPrintf("%c", 0x30+(j%10));
}
while (1)
{
sceDisplayWaitVblankStart();
sceKernelDelayThread(500000);
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_CROSS)
break;
}
to keep it as low as 169 € and keep a good margin, they should have not felt the necessity of a hardware driver for interlacing ram video :/moonlight wrote:In other words, the line order is 0, 262, 1, 263, 2, 264... argh i hate this, why the fuck they couldn't handle this in the driver instead of making the high level programs handle it.
besides, what are those video signals on PSP slim ? direct lines to component or composite lines ? not serial lines I hope so which are converted to component or composite according to the cable you plug.
Last edited by hlide on Tue Oct 16, 2007 6:40 am, edited 1 time in total.
If it is help for anyone, these are the reversed and recompilable code of dve.prx and hibari.prx (hibari is needed to make the psp slim screen display work, and probably is required for tv output too).
The clones can replace the ones of 3.60 M33 and work perfectly like the original :) For 3.71, it should be just a matter of changing the nids (only the one of imports, the one of exports are unaltered).
The code has much unknowns, and maybe not that readable, but still better than asm ;)
http://rapidshare.com/files/62786951/dv ... d.rar.html
http://rapidshare.com/files/62787712/hi ... d.rar.html
The clones can replace the ones of 3.60 M33 and work perfectly like the original :) For 3.71, it should be just a matter of changing the nids (only the one of imports, the one of exports are unaltered).
The code has much unknowns, and maybe not that readable, but still better than asm ;)
http://rapidshare.com/files/62786951/dv ... d.rar.html
http://rapidshare.com/files/62787712/hi ... d.rar.html
-
- Posts: 60
- Joined: Wed Jul 06, 2005 7:03 pm
NTSC is 525 lines in a frame, split over 2 fields, this is an extra 22 and a half per field. the first 20 lines contain the teletext (not sure what it's called outside of Eruope, but the 'hidden' text for hard of hearing or cars for sale, etc) the 21st line is for timing data (VITC) and the extra frame is droped every so often (hence NTSC-DF) to help remove the mains carrier frequency interefere with the image, but can produce visual beats in old sets.J.F. wrote:
And it is. I done figgered it out! They were even more lazy than you can imagine. The interlaced modes ARE NTSC. The screen buffer in those modes is laid out this way:
240 lines of even field
22 lines of nothing
240 lines of odd field
1 line of nothing
I was playing around with the printf some more to figure this out. Half the lines go at the vram base, and half go at vram + 262 * line_width, and only 240 of those lines in the field display anything. So the interlaced modes ARE the same as the progressive mode - 720x480. It's just laid out in an odd manner. 240+22 = 262 = one field is pretty obvious. That one extra line must be the one that's split in half to make the display interlaced.
-
- Posts: 110
- Joined: Tue Feb 27, 2007 9:43 pm
- Contact:
As I posted a while back, int sceImposeCheckVideoOut(int *val); also returns the cable info. It returns an error if no cable is detected, and 0 if there is. *val contains the cable type when 0 is returned. Impose probably calls the function you give above. :)SilverSpring wrote:0x25F47F96 sceSysconGetVideoCable
int sceSysconGetVideoCable(int *type);
Dont have a slim with me right now so I cant test it.
that impose function calls the hprm function i use in my prx, and i guess that one use the syscon. I didn't use the impose function, because it returned an error if executed in game config.J.F. wrote:As I posted a while back, int sceImposeCheckVideoOut(int *val); also returns the cable info. It returns an error if no cable is detected, and 0 if there is. *val contains the cable type when 0 is returned. Impose probably calls the function you give above. :)SilverSpring wrote:0x25F47F96 sceSysconGetVideoCable
int sceSysconGetVideoCable(int *type);
Dont have a slim with me right now so I cant test it.