[SOLVED] Drawing to the screen....

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

Moderators: cheriff, TyRaNiD

Post Reply
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

[SOLVED] Drawing to the screen....

Post by Tinnus »

*** EDIT: Solved already.


Hello... first post here although I've been spending quite a good time reading the forum, and also searched for answers for my problem (not managing to solve it). I've also done some homebrew for other platforms and am pretty good in C (and even ARM assembly).

I'm trying to port one of my apps from another platform to the PSP but I'm having trouble with the display. I've borrowed the display code from s9xpsp_tyl but it's not working right.

The original resolution is 320x240 and for now I just want to draw a 320x240 image from a buffer in RAM to the PSP screen. The s9xpsp_tyl code is basically the same from the Blit sample in the SDK, drawing vertical stripe sprites with a width of 64 each and assigning the image buffer to a texture.

I know the texture image buffer width must be block-aligned to 512 so although my image is 320x240x16bits I set the buffer to 512x240 and modified the app code accordingly.

Now, instead of the B&W text that should have appeared in the screen, I have lots of "cut" horizontal lines--seems like a width alignment problem. Sometimes I change something and it actually displays only the first line...

Here's my drawing code. Note that I call the init and sutdown functions accordingly.

Code: Select all

unsigned int __attribute__((aligned(64))) list[262144*4];

struct Vertex
{
	unsigned short u, v;
	short x, y, z;
};

unsigned short __attribute__((aligned(16))) internal_screen[512*240*2];

int swap_buf;

#define SLICE_SIZE 64 // change this to experiment with different page-cache sizes

#define	FRAMESIZE	0x44000			//in byte (512*272*2)

#define RELEASE

void blit_reinit(void){
	sceGuStart(GU_DIRECT,list);
	swap_buf=0;
	sceGuDrawBuffer(GU_PSM_5650,(void*)0,512);
	sceGuDispBuffer(480,272,(void*)FRAMESIZE,512);
	sceGuOffset(2048 - (480/2),2048 - (272/2));
	sceGuViewport(2048,2048,480,272);

	/*sceGuDepthBuffer((void*)(FRAMESIZE*2),256);

	sceGuEnable(GU_DEPTH_TEST);
	sceGuDepthRange(256,0);
	sceGuDepthOffset(0);
	sceGuDepthFunc(GU_GREATER);*/

	sceGuFinish();
	sceGuSync(0,0);


	sceGuStart(GU_DIRECT,list);

	/*sceGuEnable(GU_SCISSOR_TEST);
	sceGuScissor(0,0,256,240);*/

	sceGuEnable(GU_TEXTURE_2D);
	sceGuTexMode(GU_PSM_5650,0,0,0); // 8-bit image
	sceGuTexFilter(GU_NEAREST,GU_NEAREST);

	sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGBA);
	sceGuTexScale(1.0f/512.0f,1.0f/512.0f);
	sceGuTexOffset(0,0);

	//sceGuEnable(GU_ALPHA_TEST);
	//sceGuAlphaFunc(GU_EQUAL,0,0x1);

	sceGuClutMode(GU_PSM_5650,0,255,0);

	sceGuClearColor(0);
	sceGuClear(GU_COLOR_BUFFER_BIT);

	sceGuFinish();
	sceGuSync(0,0);
	sceDisplayWaitVblankStart();

	//cache stuff
//	tile_reset_cache();
}

void blit_init(void){
	//cache stuff
//	tile_init_cache();

	// setup GU
	sceGuInit();
	sceGuDisplay(1);
	blit_reinit();
}

void guClear(int dst_w,int dst_h){
	unsigned int cx,cy;
	sceGuStart(GU_DIRECT,list);
	sceGuEnable(GU_SCISSOR_TEST);

#ifdef RELEASE
  cx=(480-dst_w)/2;
  cy=(272-dst_h)/2;
#else
	cx=cy=0;
#endif
  sceGuScissor(cx,cy,cx+dst_w,cy+dst_h);

  sceGuClearColor(0);
  sceGuClear(GU_COLOR_BUFFER_BIT);
  sceGuFinish();
  sceGuSync(0,0);
}




#define os9x_screenWidth  320
#define os9x_screenHeight 240
#define os9x_screenLeft   0
#define os9x_screenTop    0

void guDrawBuffer(unsigned short* video_buffer,int src_w,int src_h,int src_pitch,int dst_w,int dst_h){
  unsigned int j,cx,cy;
  struct Vertex* vertices,*vertices_ptr;
  sceGuStart(GU_DIRECT,list);

  /*sceGuOffset(2048 - (480/2),2048 - (272/2));
	sceGuViewport(2048,2048,480,272);*/

	sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB);

  sceGuDrawBufferList(GU_PSM_5650,(void*)(512*272*2*swap_buf),512);
  sceGuEnable(GU_SCISSOR_TEST);
  //sceGuDisable(GU_SCISSOR_TEST);

#ifdef RELEASE
  cx=(480-dst_w)/2;
  cy=(272-dst_h)/2;
#else
	cx=cy=0;
#endif
  sceGuScissor(cx,cy,cx+dst_w,cy+dst_h);


  sceGuDisable(GU_DEPTH_TEST);
  sceGuDisable(GU_ALPHA_TEST);

  sceGuTexMode(GU_PSM_5650,0,0,0);

  sceKernelDcacheWritebackInvalidateAll();

  sceGuTexImage(0,src_w,src_w,src_pitch,video_buffer); 
  sceGuTexFunc(GU_TFX_REPLACE,0);
  /*if (os9x_smoothing) sceGuTexFilter(GU_LINEAR,GU_LINEAR);
  else*/ sceGuTexFilter(GU_NEAREST,GU_NEAREST);
  sceGuTexScale(1.0f/src_w,1.0f/src_w); // scale UVs to 0..1
  sceGuTexOffset(0,0);
  sceGuTexWrap(GU_CLAMP,GU_CLAMP);

  vertices = (struct Vertex*)sceGuGetMemory(2*(1+src_w/SLICE_SIZE) * sizeof(struct Vertex));
  vertices_ptr=vertices;

  for &#40;j = 0; &#40;j+SLICE_SIZE&#41; < src_w; j = j+SLICE_SIZE&#41; &#123;

    vertices_ptr&#91;0&#93;.u = j; vertices_ptr&#91;0&#93;.v = &#40;240-src_h&#41;/2;
    vertices_ptr&#91;0&#93;.x = cx+j*&#40;dst_w+os9x_screenWidth&#41;/src_w+os9x_screenLeft; vertices_ptr&#91;0&#93;.y = cy+0+os9x_screenTop; vertices_ptr&#91;0&#93;.z = 0;
    vertices_ptr&#91;1&#93;.u = j+SLICE_SIZE; vertices_ptr&#91;1&#93;.v = src_h-&#40;240-src_h&#41;/2;
    vertices_ptr&#91;1&#93;.x = cx+&#40;j+SLICE_SIZE&#41;*&#40;dst_w+os9x_screenWidth&#41;/src_w+os9x_screenLeft; vertices_ptr&#91;1&#93;.y = cy+dst_h+os9x_screenHeight+os9x_screenTop; vertices_ptr&#91;1&#93;.z = 0;

    vertices_ptr+=2;
  &#125;
  if &#40;j<src_w&#41;&#123;
    vertices_ptr&#91;0&#93;.u = j; vertices_ptr&#91;0&#93;.v = &#40;240-src_h&#41;/2;
    vertices_ptr&#91;0&#93;.x = cx+j*&#40;dst_w+os9x_screenWidth&#41;/src_w+os9x_screenLeft; vertices_ptr&#91;0&#93;.y = cy+0+os9x_screenTop; vertices_ptr&#91;0&#93;.z = 0;
    vertices_ptr&#91;1&#93;.u = src_w; vertices_ptr&#91;1&#93;.v = src_h-&#40;240-src_h&#41;/2;
    vertices_ptr&#91;1&#93;.x = cx+&#40;dst_w+os9x_screenWidth&#41;+os9x_screenLeft; vertices_ptr&#91;1&#93;.y = cy+dst_h+os9x_screenHeight+os9x_screenTop; vertices_ptr&#91;1&#93;.z = 0;
    vertices_ptr+=2;
  &#125;
  sceGuDrawArray&#40;GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,vertices_ptr-vertices,0,vertices&#41;;



  /*vertices = &#40;struct Vertex*&#41;sceGuGetMemory&#40;2 * sizeof&#40;struct Vertex&#41;&#41;;

  	vertices&#91;0&#93;.u = 0; vertices&#91;0&#93;.v = 0;
  	vertices&#91;0&#93;.x = cx; vertices&#91;0&#93;.y = cy; vertices&#91;0&#93;.z = 0;

  	vertices&#91;1&#93;.u = 320; vertices&#91;1&#93;.v = 240;
	vertices&#91;1&#93;.x = cx+320; vertices&#91;1&#93;.y = cy+240; vertices&#91;1&#93;.z = 0;

  sceGuDrawArray&#40;GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices&#41;;*/


  sceGuFinish&#40;&#41;;
  sceGuSync&#40;0,0&#41;;

  sceDisplayWaitVblankStart&#40;&#41;; //or not?

  sceGuSwapBuffers&#40;&#41;;
  swap_buf^=1;
	//pg_drawframe=swap_buf^1;
&#125;

void blit_shutdown&#40;&#41;&#123;
  sceGuTerm&#40;&#41;;
&#125;

void video_flip&#40;void&#41; //called from inside the app
&#123;
	guDrawBuffer&#40;internal_screen,320,240,512,320,240&#41;;
&#125;
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
Post Reply