Using the TV out in homebrew, whatever cable, full screen

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Using the TV out in homebrew, whatever cable, full screen

Post by moonlight »

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
Last edited by moonlight on Mon Oct 15, 2007 6:22 am, edited 2 times in total.
gambiting
Posts: 154
Joined: Thu Aug 17, 2006 5:39 pm

Post by gambiting »

Oh man that's sweeeeeeet! But please,upload it on rapidshare,becouse Poland is banned on megaupload :( I'm getting myself a composite cable this week so I will be able to test it :D:D:D:D:D:D:D:D
jas0nuk
Posts: 137
Joined: Thu Apr 27, 2006 8:00 am

Post by jas0nuk »

Awesome, thanks DAX :D

Here it is on sendspace, gambiting: http://www.sendspace.com/file/d2ls7q
gambiting
Posts: 154
Joined: Thu Aug 17, 2006 5:39 pm

Post by gambiting »

jas0nuk wrote:Awesome, thanks DAX :D

Here it is on sendspace, gambiting: http://www.sendspace.com/file/d2ls7q
Thanks,can't wait to test it :D:D
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

That is just too cool! Works great on my slim. Can't wait to work it into homebrew. :)
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

More great work :)
Thanks!
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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.
I don't know, but those are the values the XMB set without any doubts.

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.
FreePlay
Posts: 71
Joined: Wed Jan 04, 2006 6:53 pm
Location: Schenectady, New York, USA

Post by FreePlay »

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).
cooleyes
Posts: 123
Joined: Thu May 18, 2006 3:30 pm

Post by cooleyes »

That is just too cool!
I will try to use it in my PPA project.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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).
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.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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
Last edited by moonlight on Tue Oct 16, 2007 6:50 am, edited 1 time in total.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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:

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 &#40;y = 0; y < 240; y++&#41;
		&#123;		
			for &#40;x = 0; x < 720; x++&#41;
			&#123;
				vram&#91;&#40;y*768&#41; + x&#93; = color;
			&#125;
		&#125;
		
		sceDisplayWaitVblankStart&#40;&#41;;
		sceKernelDelayThread&#40;500000&#41;;

		sceCtrlReadBufferPositive&#40;&pad, 1&#41;;

		if &#40;pad.Buttons & PSP_CTRL_CROSS&#41;
			break;	
	&#125;
But "lines" appear.
The following code do the same, but lines do not appear:

Code: Select all

pspDveMgrSetVideoOut&#40;u, displaymode, width, height, 1, 15, 0&#41;;
	sceDisplaySetFrameBuf&#40;vram, 768, PSP_DISPLAY_PIXEL_FORMAT_8888, 1&#41;;

	while &#40;1&#41;
	&#123;	
		u32 color = sceKernelUtilsMt19937UInt&#40;&ctx&#41; & 0x00FFFFFF;
		
		for &#40;y = 0; y < 503; y++&#41;
		&#123;		
			for &#40;x = 0; x < 720; x++&#41;
			&#123;
				vram&#91;&#40;y*768&#41; + x&#93; = color;
			&#125;
		&#125;
		
		sceDisplayWaitVblankStart&#40;&#41;;
		sceKernelDelayThread&#40;500000&#41;;

		sceCtrlReadBufferPositive&#40;&pad, 1&#41;;

		if &#40;pad.Buttons & PSP_CTRL_CROSS&#41;
			break;	
	&#125;
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.
Last edited by moonlight on Tue Oct 16, 2007 2:32 am, edited 1 time in total.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Post by crazyc »

J.F. wrote:That would be the REALLY cheap way to do it.
Maybe some engineers at Sony are just nostalgic.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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
Yes, component interlace seems to work exactly in same way.

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.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

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.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

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.
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.
Last edited by hlide on Tue Oct 16, 2007 5:15 am, edited 1 time in total.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

hlide wrote:
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.
Did you forget PAL ?
the cables are supossed to require a TV supporting NTSC...
gambiting
Posts: 154
Joined: Thu Aug 17, 2006 5:39 pm

Post by gambiting »

moonlight wrote:
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.
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
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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.
You'll have to modify the code more for it not to show the lines.
If it is usefull for you, the following code paints a part of the screen of a color without lines:

Code: Select all

for &#40;y = 0; y < 64; y++&#41;
&#123;		
	for &#40;x = 0; x < 720; x++&#41;
	&#123;
		vram&#91;&#40;y*768&#41; + x&#93; = color;
		vram&#91;&#40;y+262&#41;*768 + x&#93; = color;
	&#125;			
&#125;
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.
Last edited by moonlight on Tue Oct 16, 2007 5:21 am, edited 1 time in total.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

moonlight wrote:
hlide wrote:Did you forget PAL ?
the cables are supossed to require a TV supporting NTSC...
yes I realised it too late. I modified the message but you replied meanwhile
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

moonlight wrote:
hlide wrote:
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.
Did you forget PAL ?
the cables are supossed to require a TV supporting NTSC...
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.

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&#58;//www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * scr_printf.c - Debug screen functions.
 *
 * Copyright &#40;c&#41; 2005 Marcus R. Brown <[email protected]>
 * Copyright &#40;c&#41; 2005 James Forshaw <[email protected]>
 * Copyright &#40;c&#41; 2005 John Kelley <[email protected]>
 *
 * $Id&#58; scr_printf.c 2319 2007-09-30 15&#58;58&#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&#40; int Y&#41;;
void pspDveScreenInit&#40;int mode&#41;;
void pspDveScreenInitEx&#40;void *vram_base, int mode, int setup&#41;;
void pspDveScreenPrintf&#40;const char *fmt, ...&#41; __attribute__&#40;&#40;format&#40;printf,1,2&#41;&#41;&#41;;
void pspDveScreenKprintf&#40;const char *format, ...&#41; __attribute__&#40;&#40;format&#40;printf,1,2&#41;&#41;&#41;;
void pspDveScreenEnableBackColor&#40;int enable&#41;;
void pspDveScreenSetBackColor&#40;u32 color&#41;;
void pspDveScreenSetTextColor&#40;u32 color&#41;;
void pspDveScreenSetColorMode&#40;int mode&#41;;
void pspDveScreenPutChar&#40;int x, int y, u32 color, u8 ch&#41;;
void pspDveScreenSetXY&#40;int x, int y&#41;;
void pspDveScreenSetOffset&#40;int offset&#41;;
void pspDveScreenSetBase&#40;u32* base&#41;;
int pspDveScreenGetX&#40;void&#41;;
int pspDveScreenGetY&#40;void&#41;;
void pspDveScreenClear&#40;void&#41;;
int pspDveScreenPrintData&#40;const char *buff, int size&#41;;
int pspDveScreenPuts&#40;const char *str&#41;;

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 = &#40;u32 *&#41; 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&#40;u32 color&#41;
&#123;
	int r, g, b;

	b = &#40;color >> 19&#41; & 0x1F;
	g = &#40;color >> 10&#41; & 0x3F;
	r = &#40;color >> 3&#41; & 0x1F;

	return r | &#40;g << 5&#41; | &#40;b << 11&#41;;
&#125;

static u16 convert_8888_to_5551&#40;u32 color&#41;
&#123;
	int r, g, b, a;

	a = &#40;color >> 24&#41; ? 0x8000 &#58; 0;
	b = &#40;color >> 19&#41; & 0x1F;
	g = &#40;color >> 11&#41; & 0x1F;
	r = &#40;color >> 3&#41; & 0x1F;

	return a | r | &#40;g << 5&#41; | &#40;b << 10&#41;;
&#125;

static u16 convert_8888_to_4444&#40;u32 color&#41;
&#123;
	int r, g, b, a;

	a = &#40;color >> 28&#41; & 0xF;
	b = &#40;color >> 20&#41; & 0xF;
	g = &#40;color >> 12&#41; & 0xF;
	r = &#40;color >> 4&#41; & 0xF;

	return &#40;a << 12&#41; | r | &#40;g << 4&#41; | &#40;b << 8&#41;;
&#125;

static void clear_screen_16&#40;u16 color&#41;
&#123;
	 int x;
	 u16 *vram = g_vram_base;

	vram += &#40;g_vram_offset >> 1&#41;;

	 for&#40;x = 0; x < &#40;PSP_LINE_SIZE * PSP_SCREEN_HEIGHT&#41;; x++&#41;
	 &#123;
		*vram++ = color;
	 &#125;
&#125;

static void clear_screen_32&#40;u32 color&#41;
&#123;
	 int x;
	 u32 *vram = g_vram_base;
	 vram +=	&#40;g_vram_offset>>2&#41;;

	 for&#40;x = 0; x < &#40;PSP_LINE_SIZE * PSP_SCREEN_HEIGHT&#41;; x++&#41;
	 &#123;
		*vram++ = color;
	 &#125;
&#125;

static void clear_screen&#40;u32 color&#41;
&#123;
	if&#40;g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888&#41;
	&#123;
		clear_screen_32&#40;color&#41;;
	&#125;
	else
	&#123;
		u16 c = 0;
		switch&#40;g_vram_mode&#41;
		&#123;
			case PSP_DISPLAY_PIXEL_FORMAT_565&#58;
			c = convert_8888_to_565&#40;color&#41;;
			break;
			case PSP_DISPLAY_PIXEL_FORMAT_5551&#58;
			c = convert_8888_to_5551&#40;color&#41;;
			break;
			case PSP_DISPLAY_PIXEL_FORMAT_4444&#58;
			c = convert_8888_to_4444&#40;color&#41;;
			break;
		&#125;;
		clear_screen_16&#40;c&#41;;
	&#125;
&#125;

void pspDveScreenInitEx&#40;void *vram_base, int mode, int setup&#41;
&#123;
	switch&#40;mode&#41;
	&#123;
		case PSP_DISPLAY_PIXEL_FORMAT_565&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_5551&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_4444&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_8888&#58;
		break;
		default&#58;
		mode = PSP_DISPLAY_PIXEL_FORMAT_8888;
	&#125;;

	X = Y = 0;
	/* Place vram in uncached memory */
	if&#40;vram_base == NULL&#41;
	&#123;
		vram_base = &#40;void*&#41; &#40;0x40000000 | &#40;u32&#41; sceGeEdramGetAddr&#40;&#41;&#41;;
	&#125;
	g_vram_base = vram_base;
	g_vram_offset = 0;
	g_vram_mode = mode;
	if&#40;setup&#41;
	&#123;
		switch &#40;setup & 0x7f&#41;
		&#123;
			case 0&#58;
			// composite
			pspDveMgrSetVideoOut&#40;2, 0x1d1, 720, 503, 1, 15, 0&#41;;
			PSP_SCREEN_HEIGHT = 503;
			break;
			case 1&#58;
			// component progressive
			pspDveMgrSetVideoOut&#40;0, 0x1d2, 720, 480, 1, 15, 0&#41;;
			PSP_SCREEN_HEIGHT = 480;
			break;
			case 2&#58;
			// component interlace
			pspDveMgrSetVideoOut&#40;0, 0x1d1, 720, 503, 1, 15, 0&#41;;
			PSP_SCREEN_HEIGHT = 503;
			break;
		&#125;

		sceDisplaySetFrameBuf&#40;&#40;void *&#41; g_vram_base, PSP_LINE_SIZE, mode, 1&#41;;
	&#125;
	clear_screen&#40;bg_col&#41;;
	init = 1;
&#125;

void pspDveScreenInit&#40;int vmode&#41;
&#123;
	X = Y = 0;
	pspDveScreenInitEx&#40;NULL, PSP_DISPLAY_PIXEL_FORMAT_8888, vmode|0x80&#41;;
&#125;

void pspDveScreenEnableBackColor&#40;int enable&#41;
&#123;
	bg_enable = enable;
&#125;

void pspDveScreenSetBackColor&#40;u32 colour&#41;
&#123;
	bg_col = colour;
&#125;

void pspDveScreenSetTextColor&#40;u32 colour&#41;
&#123;
	fg_col = colour;
&#125;

void pspDveScreenSetColorMode&#40;int mode&#41;
&#123;
	switch&#40;mode&#41;
	&#123;
		case PSP_DISPLAY_PIXEL_FORMAT_565&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_5551&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_4444&#58;
		case PSP_DISPLAY_PIXEL_FORMAT_8888&#58;
		break;
		default&#58;
		mode = PSP_DISPLAY_PIXEL_FORMAT_8888;
	&#125;;

	g_vram_mode = mode;
&#125;

int pspDveScreenGetX&#40;&#41;
&#123;
	return X;
&#125;

int pspDveScreenGetY&#40;&#41;
&#123;
	return Y;
&#125;

void pspDveScreenClear&#40;&#41;
&#123;
	int y;

	if&#40;!init&#41;
	&#123;
		return;
	&#125;

	for&#40;y=0;y<MY;y++&#41;
	&#123;
		_pspDveScreenClearLine&#40;y&#41;;
	&#125;

	pspDveScreenSetXY&#40;0,0&#41;;
	clear_screen&#40;bg_col&#41;;
&#125;

void pspDveScreenSetXY&#40;int x, int y&#41;
&#123;
	if&#40; x<MX && x>=0 &#41; X=x;
	if&#40; y<MY && y>=0 &#41; Y=y;
&#125;

void pspDveScreenSetOffset&#40;int offset&#41;
&#123;
	g_vram_offset = offset;
&#125;

void pspDveScreenSetBase&#40;u32* base&#41;
&#123;
	g_vram_base = base;
&#125;

extern u8 msx&#91;&#93;;

static void debug_put_char_32&#40;int x, int y, u32 color, u32 bgc, u8 ch&#41;
&#123;
	int i,j, l;
	u8	*font;
	u32 *vram_ptr;
	u32 *vram1;
	u32 *vram2;

	if&#40;!init&#41;
	&#123;
		return;
	&#125;

	if &#40;PSP_SCREEN_HEIGHT == 480&#41;
	&#123;
		vram1 = g_vram_base;
		vram1 += &#40;g_vram_offset >> 2&#41; + x;
		vram1 += y * PSP_LINE_SIZE;

		font = &msx&#91; &#40;int&#41;ch * 8&#93;;
		for &#40;i=l=0; i < 8; i++, l+= 8, font++&#41;
		&#123;
			vram_ptr  = vram1;
			for &#40;j=0; j < 8; j++&#41;
			&#123;
				if &#40;&#40;*font & &#40;128 >> j&#41;&#41;&#41;
					*vram_ptr = color;
				else if&#40;bg_enable&#41;
					*vram_ptr = bgc;
				vram_ptr++;
			&#125;
			vram1 += PSP_LINE_SIZE;
		&#125;
	&#125;
	else
	&#123;
		vram1 = g_vram_base;
		vram1 += &#40;g_vram_offset >> 3&#41; + x;
		vram1 += &#40;y>>1&#41; * PSP_LINE_SIZE;
		vram2 = vram1;
		vram2 += PSP_FIELD_OFFSET * PSP_LINE_SIZE;

		font = &msx&#91; &#40;int&#41;ch * 8&#93;;
		for &#40;i=l=0; i < 8; i++, l+= 8, font++&#41;
		&#123;
			vram_ptr  = &#40;i & 1&#41; ? vram1 &#58; vram2;
			for &#40;j=0; j < 8; j++&#41;
			&#123;
				if &#40;&#40;*font & &#40;128 >> j&#41;&#41;&#41;
					*vram_ptr = color;
				else if&#40;bg_enable&#41;
					*vram_ptr = bgc;
				vram_ptr++;
			&#125;
			if &#40;i & 1&#41;
				vram1 += PSP_LINE_SIZE;
			else
				vram2 += PSP_LINE_SIZE;
		&#125;
	&#125;
&#125;

static void debug_put_char_16&#40;int x, int y, u16 color, u16 bgc, u8 ch&#41;
&#123;
	int i,j, l;
	u8	*font;
	u16 *vram_ptr;
	u16 *vram1;
	u16 *vram2;

	if&#40;!init&#41;
	&#123;
		return;
	&#125;

	if &#40;PSP_SCREEN_HEIGHT == 480&#41;
	&#123;
		vram1 = g_vram_base;
		vram1 += &#40;g_vram_offset >> 1&#41; + x;
		vram1 += y * PSP_LINE_SIZE;

		font = &msx&#91; &#40;int&#41;ch * 8&#93;;
		for &#40;i=l=0; i < 8; i++, l+= 8, font++&#41;
		&#123;
			vram_ptr  = vram1;
			for &#40;j=0; j < 8; j++&#41;
			&#123;
				if &#40;&#40;*font & &#40;128 >> j&#41;&#41;&#41;
					*vram_ptr = color;
				else if&#40;bg_enable&#41;
					*vram_ptr = bgc;
				vram_ptr++;
			&#125;
			vram1 += PSP_LINE_SIZE;
		&#125;
	&#125;
	else
	&#123;
		vram1 = g_vram_base;
		vram1 += &#40;g_vram_offset >> 1&#41; + x;
		vram1 += &#40;y>>1&#41; * PSP_LINE_SIZE;
		vram2 = vram1;
		vram2 += PSP_FIELD_OFFSET * PSP_LINE_SIZE;

		font = &msx&#91; &#40;int&#41;ch * 8&#93;;
		for &#40;i=l=0; i < 8; i++, l+= 8, font++&#41;
		&#123;
			vram_ptr  = &#40;i & 1&#41; ? vram1 &#58; vram2;
			for &#40;j=0; j < 8; j++&#41;
			&#123;
				if &#40;&#40;*font & &#40;128 >> j&#41;&#41;&#41;
					*vram_ptr = color;
				else if&#40;bg_enable&#41;
					*vram_ptr = bgc;
				vram_ptr++;
			&#125;
			if &#40;i & 1&#41;
				vram1 += PSP_LINE_SIZE;
			else
				vram2 += PSP_LINE_SIZE;
		&#125;
	&#125;
&#125;

void
pspDveScreenPutChar&#40; int x, int y, u32 color, u8 ch&#41;
&#123;
	if&#40;g_vram_mode == PSP_DISPLAY_PIXEL_FORMAT_8888&#41;
	&#123;
		debug_put_char_32&#40;x, y, color, bg_col, ch&#41;;
	&#125;
	else
	&#123;
		u16 c = 0;
		u16 b = 0;
		switch&#40;g_vram_mode&#41;
		&#123;
			case PSP_DISPLAY_PIXEL_FORMAT_565&#58;
			c = convert_8888_to_565&#40;color&#41;;
			b = convert_8888_to_565&#40;bg_col&#41;;
			break;
			case PSP_DISPLAY_PIXEL_FORMAT_5551&#58;
			c = convert_8888_to_5551&#40;color&#41;;
			b = convert_8888_to_5551&#40;bg_col&#41;;
			break;
			case PSP_DISPLAY_PIXEL_FORMAT_4444&#58;
			c = convert_8888_to_4444&#40;color&#41;;
			b = convert_8888_to_4444&#40;bg_col&#41;;
			break;
		&#125;;
		debug_put_char_16&#40;x, y, c, b, ch&#41;;
	&#125;
&#125;

void  _pspDveScreenClearLine&#40; int Y&#41;
&#123;
	int i;

	if&#40;bg_enable&#41;
	&#123;
		for &#40;i=0; i < MX; i++&#41;
		&#123;
			pspDveScreenPutChar&#40; i*7 , Y * 8, bg_col, 219&#41;;
		&#125;
	&#125;
&#125;

/* Print non-nul terminated strings */
int pspDveScreenPrintData&#40;const char *buff, int size&#41;
&#123;
	int i;
	int j;
	char c;

	if&#40;!init&#41;
	&#123;
		return 0;
	&#125;

	for &#40;i = 0; i < size; i++&#41;
	&#123;
		c = buff&#91;i&#93;;
		switch &#40;c&#41;
		&#123;
			case '\n'&#58;
			X = 0;
			Y ++;
			if &#40;Y == MY&#41;
			Y = 0;
			_pspDveScreenClearLine&#40;Y&#41;;
			break;
			case '\t'&#58;
			for &#40;j = 0; j < 5; j++&#41; &#123;
				pspDveScreenPutChar&#40; X*7 , Y * 8, fg_col, ' '&#41;;
				X++;
			&#125;
			break;
			default&#58;
			pspDveScreenPutChar&#40; X*7 , Y * 8, fg_col, c&#41;;
			X++;
			if &#40;X == MX&#41;
			&#123;
				X = 0;
				Y++;
				if &#40;Y == MY&#41;
					Y = 0;
				_pspDveScreenClearLine&#40;Y&#41;;
			&#125;
		&#125;
	&#125;

	return i;
&#125;

int pspDveScreenPuts&#40;const char *str&#41;
&#123;
	return pspDveScreenPrintData&#40;str, strlen&#40;str&#41;&#41;;
&#125;

void pspDveScreenPrintf&#40;const char *format, ...&#41;
&#123;
	va_list	opt;
	char	buff&#91;2048&#93;;
	int		bufsz;

	va_start&#40;opt, format&#41;;
	bufsz = vsnprintf&#40; buff, &#40;size_t&#41; sizeof&#40;buff&#41;, format, opt&#41;;
	&#40;void&#41; pspDveScreenPrintData&#40;buff, bufsz&#41;;
&#125;
And the main part of main.c that prints the lines:

Code: Select all

	pspDveScreenInit&#40;2&#41;;
	pspDveScreenClear&#40;&#41;;

	for &#40;i = 0; i < &#40;480/8&#41;; i++&#41;
	&#123;
		if &#40;i != 30&#41;
			pspDveScreenPrintf&#40;" Line #%d\n", i&#41;;
		else
			for &#40;j = 0; j < &#40;720/7&#41;; j++&#41;
				pspDveScreenPrintf&#40;"%c", 0x30+&#40;j%10&#41;&#41;;
	&#125;

	while &#40;1&#41;
	&#123;
		sceDisplayWaitVblankStart&#40;&#41;;
		sceKernelDelayThread&#40;500000&#41;;

		sceCtrlReadBufferPositive&#40;&pad, 1&#41;;

		if &#40;pad.Buttons & PSP_CTRL_CROSS&#41;
			break;
	&#125;
The value passed to pspDveScreenInit() is 0 for composite, 1 for progressive component, and 2 for interlaced component.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

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.
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 :/

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.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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
white rabbit
Posts: 60
Joined: Wed Jul 06, 2005 7:03 pm

Post by white rabbit »

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.
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.
SilverSpring
Posts: 110
Joined: Tue Feb 27, 2007 9:43 pm
Contact:

Post by SilverSpring »

0x25F47F96 sceSysconGetVideoCable

int sceSysconGetVideoCable(int *type);

Dont have a slim with me right now so I cant test it.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

SilverSpring wrote:0x25F47F96 sceSysconGetVideoCable

int sceSysconGetVideoCable(int *type);

Dont have a slim with me right now so I cant test it.
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. :)
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

J.F. wrote:
SilverSpring wrote:0x25F47F96 sceSysconGetVideoCable

int sceSysconGetVideoCable(int *type);

Dont have a slim with me right now so I cant test it.
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. :)
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.
Post Reply