Preview of pdf reader for psp

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

Moderators: cheriff, TyRaNiD

Post Reply
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Preview of pdf reader for psp

Post by sauron_le_noir »

At this link you have a preview wat my homebrew can do
there is no filechosser yet it take always from
psp/game/psppdf/test.pdf you may replace test.pdf with any of your pdf's
LTRIGGER backward page RTRIGGER forward page
analogic stick navigation into the page
UP key = zoom in
Dow key = zoom out
X = quit pdf reader
Known bug zoom > 1.7 may crash the homebrew with a enought memory error
zoom < 0 if the bitmap rendere is less than 480x272 garbage on the screen not covered by the bimap
I try the implementation of cpu at hight speed this week-end
fix the garbage
and try to allocate more memory if slim detected

the link for the preview for a slim is



http://www.enterinmydream.info/~sauronl ... review.zip
and for the fat

http://www.enterinmydream.info/~sauronl ... ew_fat.zip

see the next discution why a version for fat a another for slim

it's a debug build if the homebrew crash i'm very interested int the 2 or 3 txt files
generated in the folder where the homebrew is launched they give me indication
about the heap space (malloc and free objects ...).
The code for illegal pdfs or endomaged pdf is not tested yet i give in the zip
a test.pdf make with openoffice

PS: i have tested the homebrew on a psp slim with 4.01M33
Last edited by sauron_le_noir on Sat Aug 09, 2008 5:30 am, edited 2 times in total.
pspZorba
Posts: 156
Joined: Sat Sep 22, 2007 11:45 am
Location: NY

Post by pspZorba »

I have tested on a fat with 4.01 M33-2 without K1.5.

I just have a black screen and a shutdown down as if there was a memory overwritten ( ecrasement memoire ?)

Did you compile with PSP_LARGE_MEMORY=1 ?

[edit] no txt files generated[\edit]
--pspZorba--
NO to K1.5 !
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

yes indeed not tested on fat here is the makefile
TARGET = psp_pdf

OBJS = psp_pdf.o splashscreen.o filechooser.o rendering.o
PSP_FW_VERSION=401
PSP_PDF_VERSION=1.0.0
PSPSDK=$(shell psp-config --pspsdk-path)
PSPDIR=$(shell psp-config --psp-prefix)
PSP_LARGE_MEMORY = 1
INCDIR =

CFLAGS = -O0 -G0 -Wall -g -DDEBUG -D_DEBUG -D_DEBUG_LOG -D_DEBUG_MEMORY -D__PSP__ -DTRI_SUPPORT_PNG -I $(PSPDIR)/includre -I $(PSPDIR)/include/freetype2 -I../../include

CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti

ASFLAGS = $(CFLAGS)



LIBDIR =

LDFLAGS =

LIBS = -ltri -lmupdf -lstream -lworld -lraster -lfonts -lbase -ljpeg -lpsprtc -lpspgum -lpspgu -lpng -lz -lm -lfreetype



EXTRA_TARGETS = EBOOT.PBP

PSP_EBOOT_TITLE = PSP PDF Reader



PSPSDK=$(shell psp-config --pspsdk-path)

include $(PSPSDK)/lib/build.mak



and in psp_pdf.c
PSP_MODULE_INFO("PSPPDF", PSP_MODULE_USER, 1, 1);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER|PSP_THREAD_ATTR_VFPU);
PSP_HEAP_SIZE_KB(30000);


can you send me the 3 txt files generated in the folder
serge_sterck@hotmail.com thx
i try to steal the fat psp of my wife but that's not so easy
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

i've recompiled the homebrew without large_memory stuff and i reduce
the PSP_HEAP_SIZE_KB from 30000 to 20000 and guess wat
it works on the fat psp of my wife
can i dynamicly update PSP_HEAP_SIZE if i detect a slim ?

the link for the slim
http://www.enterinmydream.info/~sauronl ... review.zip
the link for the fat :
http://www.enterinmydream.info/~sauronl ... ew_fat.zip
Last edited by sauron_le_noir on Sat Aug 09, 2008 5:31 am, edited 1 time in total.
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

With this the fat can only go to the zoom at 1.5 at 1.6 i have a not enougth memory
grrrrrrrrrrrr.
on the slim you can go to 1.7 so the dilema 2 compilations and zoom reduce capacity for the fat
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

sauron_le_noir wrote:i've recompiled the homebrew without large_memory stuff and i reduce
the PSP_HEAP_SIZE_KB from 30000 to 20000 and guess wat
it works on the fat psp of my wife
can i dynamicly update PSP_HEAP_SIZE if i detect a slim ?

the link for the slim
http://www.enterinmydream.info/~sauronl ... review.zip
the link for the fat :
http://www.enterinmydream.info/~sauronl ... ew_fat.zip
Why don't you use PSP_HEAP_SIZE_MAX? It will already allocate max memory in both.
Anyways, you can change the hep before any malloc operations. In the file where you wrote PSP_HEAP_SIZE_KB, do in main function "sce_newlib_heap_kb_size = desired_size;"
pspZorba
Posts: 156
Joined: Sat Sep 22, 2007 11:45 am
Location: NY

Post by pspZorba »

it is working now.

I tried a ppt transformed in pdf.

. I can see horizontal lines through the screen.
. When you zoom out a lot you have side effects (for my test 0.6).

but otherwise it is fine.
--pspZorba--
NO to K1.5 !
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

yep forget to set ARGB buffer to null before fill it up
can you send me your pdf and the zoom factor when you have problems


i have see it when zoom factor is < 0.6 and zoom factor > 1.6 on slim because
on fat in break due to lack of memory at zoom 1.5
on 1.7 zoom the library tri give it up because the bitmap became greater than 1024x1024.
tri was better than oslib (limitation on bitmap 512x512) but cannot render bitmap higher than 1024x1024
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

sauron_le_noir wrote: tri was better than oslib (limitation on bitmap 512x512) but cannot render bitmap higher than 1024x1024
I was expecting it to be able to handle more than that, though I never tested it really. Either it's another hardware limitation (doubtful) or I just forgot something in the code... I'll have a look at the image drawing code in openTri tomorrow.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

10000000000

Post by Raphael »

Raphael wrote:
sauron_le_noir wrote: tri was better than oslib (limitation on bitmap 512x512) but cannot render bitmap higher than 1024x1024
I was expecting it to be able to handle more than that, though I never tested it really. Either it's another hardware limitation (doubtful) or I just forgot something in the code... I'll have a look at the image drawing code in openTri tomorrow.
As it seems, it's indeed another hardware limitation on the maximum texture buffer width being 1024 (and it really needs to be a power of two... I was expecting that at least that parameter isn't bound to that rule as it's submitted as plain 16bit value rather than the log2 of the value as is with texture width/texture height). So the next bigger legal texture buffer width would be 2048, and the output is the same as with 0, while all 1024 < value < 2048 will get clamped down to 1024. Most likely GU only uses 11 bits for that value and truncates to power of two... Why they didn't use 10 bits when GU can only handle 512x512 texture at once max? Guess for support for the UMD videos that are 720x480.

Only solution would now be to really split the image into smaller parts on loading and then render those parts. That will be painfully ugly to handle though, especially when you're trying to render a part of the image that lies in between two or four such slices.
I'll put it on my todo list anyway, but don't expect it to be done soon.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

thx raphael but a zoom at 1.7 is very good the pdf is readable on the psp
by te way where did you found all the documentation about programming
the gu
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

There isn't any. All info was found by looking at how various games used the GU. Just look at the examples and source for existing projects.

By the way, 512 is the widest a texture can be, BUT not the widest the storage can be. Textures are limited to 512x512, but the stride for the texture can be considerably wider (up to 16 bits (65535) if I remember correctly). For 2D, you're already splitting the blits into stripes to use the texture cache better, so the 512 wide makes no real difference to your code. You just have more stripes to do.

I've done blits on a "texture" that was 1536 wide, so > 1024 is no trouble. The key is when setting the texture, you pass in a stride value that is 16 bits wide. So while you can only use up to 512 as the texels, the total width can be far greater. Just divide the total width by the stripe width and do that many stripes.
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

J.F. wrote: I've done blits on a "texture" that was 1536 wide, so > 1024 is no trouble. The key is when setting the texture, you pass in a stride value that is 16 bits wide. So while you can only use up to 512 as the texels, the total width can be far greater. Just divide the total width by the stripe width and do that many stripes.
Could you show me the exact code you used, because for me it won't work correctly for anything bigger 1024 anymore (see above). Starting from 1024 to 2047, everything gets reduced to an effective value of 1024 and everything bigger 2048 gets reduced to an effective value of 0, i.e. the function behaves as if only the least 11 bits are used to determine the stride. Also, it seems to not accept non-power of two values correctly, introducing graphical glitches.

Just so we're in sync:

Code: Select all

sceGuTexImage&#40;0, MIN&#40;512,img->stride&#41;, MIN&#40;512,img->tex_height&#41;, img->stride, img->data&#41;;
That's where I set the stride, but this behaves as said.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

here is my drawing function

void draw_psp(int pagenum,float drawzoom)
{
fz_error *error;
fz_matrix ctm;
fz_irect bbox;
fz_pixmap *pix;
char *dst_ptr;
char *src_ptr;
int i,xx,yy,w, h, bh;
triImage* bitmap_page = 0;
int page_courante;
int old_page_courante;
triFloat x = 0.f, y = 0.f;
triVec2 *pStick,oldStick;

page_courante = pagenum;
old_page_courante = -1;
oldStick.x = -1;
oldStick.y = -1;

while ( isrunning )
{
if (page_courante != old_page_courante)
{
wait_psp(page_courante,drawzoom);
error = drawloadpage(page_courante);

if (error)
goto Exit;

ctm = fz_identity();
ctm = fz_concat(ctm, fz_translate(0, -drawpage->mediabox.y1));
ctm = fz_concat(ctm, fz_scale(drawzoom, -drawzoom));
ctm = fz_concat(ctm, fz_rotate(drawrotate + drawpage->rotate));

bbox = fz_roundrect(fz_transformaabb(ctm, drawpage->mediabox));
w = bbox.x1 - bbox.x0;
h = bbox.y1 - bbox.y0;
bh = h / drawbands;

error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4);
if (error)
{
maybedie(error);
goto Exit;
}
memset(pix->samples, 0xff, pix->h * pix->w * pix->n);
error = fz_rendertreeover(drawgc, pix, drawpage->tree, ctm);
if (error)
{
maybedie(error);
goto Exit;
}

bitmap_page = triMalloc(sizeof(triImage));

bitmap_page->level = 0;

bitmap_page->levels = 0;

bitmap_page->swizzled = 0;
bitmap_page->palette = 0;
bitmap_page->level = 0;
bitmap_page->palette = 0;
bitmap_page->bits = 32;
bitmap_page->format = 3;
bitmap_page->width = pix->w;
bitmap_page->height = pix->h;
bitmap_page->tex_height = next_pow2(pix->h);
bitmap_page->stride = next_pow2(pix->w) ;
if (bitmap_page->stride>512)
bitmap_page->stride = next_mul8(pix->w);



bitmap_page->size = bitmap_page->stride*next_mul8(pix->h)*(bitmap_page->bits>>3);
bitmap_page->data = triMalloc(bitmap_page->size);
memset(bitmap_page->data,0xff,bitmap_page->size);

dst_ptr = (char *)bitmap_page->data;
char *old_dst_ptr;
for (yy = 0; yy < pix->h; yy++)
{
old_dst_ptr = dst_ptr;
for ( xx = 0; xx < pix->w; xx++)
{
int a = pix->samples[xx * pix->n + yy * pix->w * pix->n + 0];
int r = pix->samples[xx * pix->n + yy * pix->w * pix->n + 1];
int g = pix->samples[xx * pix->n + yy * pix->w * pix->n + 2];
int b = pix->samples[xx * pix->n + yy * pix->w * pix->n + 3];
*(dst_ptr+0) = r;
*(dst_ptr+1) = g;
*(dst_ptr+2) = b;
*(dst_ptr+3) = a;
dst_ptr+=4;
}
dst_ptr = old_dst_ptr+((bitmap_page->stride)*(bitmap_page->bits>>3));
}
strcpy(bitmap_page->filename,"pdf.png");
fz_droppixmap(pix);
old_page_courante = page_courante;

triSpriteMode( 480, 272, 0 );

triEnable(TRI_PSEUDO_FSAA);
triEnable(TRI_VBLANK);
}


triClear( 0xFF0000 );
triDrawSprite( 0.f, 0.f, x, y, bitmap_page );
triSwapbuffers();
triInputUpdate ();
pStick = triInputGetStick ();

// if (pStick->x != oldStick.x || pStick->y != oldStick.y)
{
if (pStick->x < 0)
{
x-=2;
if (x<0)
x+=2;
}
if (pStick->x > 0)
{
x+=2;
if (x>=(bitmap_page->width-480))
x-=2;
}
if (pStick->y < 0)
{
y-=2;
if (y<0)
y+=2;
}
if (pStick->y > 0)
{
y+=2;
if (y>=(bitmap_page->height-272))
y-=2;
}

oldStick.x = pStick->x;
oldStick.y = pStick->y;
}
if (triInputHeld (PSP_CTRL_LTRIGGER) )
{
if (page_courante > 1)
{
page_courante--;
triImageFree( bitmap_page );
drawfreepage();
x=0;
y=0;
}
}
if (triInputHeld (PSP_CTRL_RTRIGGER) )
{
if (page_courante < pdf_getpagecount(srcpages))
{
page_courante++;
triImageFree( bitmap_page );
drawfreepage();
x=0;
y=0;
}
}
if (triInputHeld (PSP_CTRL_CROSS))
{
triImageFree( bitmap_page );
drawfreepage();
isrunning = 0;
return;
}
if (triInputHeld (PSP_CTRL_RIGHT))
{

}
if (triInputHeld (PSP_CTRL_LEFT))
{

}
if (triInputHeld (PSP_CTRL_UP))
{
drawzoom += 0.1f;
old_page_courante = -1;
triImageFree( bitmap_page );
drawfreepage();

}
if (triInputHeld (PSP_CTRL_DOWN))
{
drawzoom -= 0.1f;
old_page_courante = -1;
triImageFree( bitmap_page );
drawfreepage();

}


}
Exit:
if (drawpage)
drawfreepage();
}

from triGraphics.c




void triDrawSprite( triFloat x, triFloat y, triFloat u, triFloat v, triImage* img )

{

if (img==0) return;

if (triSpriteAngle==0.f)

triDrawImage( x, y, triSpriteWidth, triSpriteHeight, u, v, u+triSpriteWidth, v+triSpriteHeight, img );

else

triDrawImageRotate( x, y, triSpriteWidth, triSpriteHeight, u, v, u+triSpriteWidth, v+triSpriteHeight, triSpriteAngle, img );

}



void triDrawImage2( triFloat x, triFloat y, triImage* img )

{

if (img==0) return;

triDrawImage( x, y, MIN(512,img->width), MIN(512,img->height), 0, 0, MIN(512,img->width), MIN(512,img->height), img );

}
void triDrawImage( triFloat x, triFloat y, triFloat width, triFloat height, // rect pos and size on screen

triFloat u0, triFloat v0, triFloat u1, triFloat v1, // area of texture to render

triImage* img )

{

#ifdef TRI_PARANOIA

if (!triInitialized) return;

#endif

if (img==0 || img->width==0 || img->height==0 || width==0 || height==0) return;



/*if (img->swizzled==0 && img->format==triPsm && (u1-u0)==width && (v1-v0)==height)

{

sceGuCopyImage( img->format, u0, v0, width, height, img->stride, img->data,

x, y, 512, triFramebuffer );

return;

}*/



if (img->format==IMG_FORMAT_T4)

{

sceGuClutMode(img->palformat, 0, 0xff, 0);

sceGuClutLoad(2, img->palette);

}

else if (img->format==IMG_FORMAT_T8)

{

sceGuClutMode(img->palformat, 0, 0xff, 0);

sceGuClutLoad(32, img->palette);

}

sceGuTexMode(img->format, 0, 0, img->swizzled);

triChar* data = img->data;

if (u1>512.f)

{

int off = (int)u0 & ~31;

data += ((off*img->bits) >> 3);

u1 -= off;

u0 -= off;

}

if (v1>512.f)

{

int off = (int)v0/* & ~15*/;

data += off*img->stride*img->bits >> 3;

v1 -= off;

v0 -= off;

}

sceGuTexImage(0, MIN(512,img->stride), MIN(512,img->tex_height), img->stride, data);



triFloat start, end;

triFloat cur_u = u0;

triFloat cur_x = x;

triFloat x_end = x + width;

triFloat slice = 64.f;

triFloat ustep = (u1-u0)/width * slice;



// blit maximizing the use of the texture-cache

for( start=0, end=width; start<end; start+=slice )

{

triVertUV* vertices = (triVertUV*)sceGuGetMemory(2 * sizeof(triVertUV));



triFloat poly_width = ((cur_x+slice) > x_end) ? (x_end-cur_x) : slice;

triFloat source_width = ((cur_u+ustep) > u1) ? (u1-cur_u) : ustep;



vertices[0].u = cur_u;

vertices[0].v = v0;

vertices[0].x = cur_x;

vertices[0].y = y;

vertices[0].z = 0;



cur_u += source_width;

cur_x += poly_width;



vertices[1].u = cur_u;

vertices[1].v = v1;

vertices[1].x = cur_x;

vertices[1].y = (y + height);

vertices[1].z = 0;



sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertices);

}

}









as you see the sumatra pdf library render the pdf on a rgb device type ARGB
i allocate a buffer transform ARGB to RGBA after this i use you code
to render the image created
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Raphael wrote:
J.F. wrote: I've done blits on a "texture" that was 1536 wide, so > 1024 is no trouble. The key is when setting the texture, you pass in a stride value that is 16 bits wide. So while you can only use up to 512 as the texels, the total width can be far greater. Just divide the total width by the stripe width and do that many stripes.
Could you show me the exact code you used, because for me it won't work correctly for anything bigger 1024 anymore (see above). Starting from 1024 to 2047, everything gets reduced to an effective value of 1024 and everything bigger 2048 gets reduced to an effective value of 0, i.e. the function behaves as if only the least 11 bits are used to determine the stride. Also, it seems to not accept non-power of two values correctly, introducing graphical glitches.

Just so we're in sync:

Code: Select all

sceGuTexImage&#40;0, MIN&#40;512,img->stride&#41;, MIN&#40;512,img->tex_height&#41;, img->stride, img->data&#41;;
That's where I set the stride, but this behaves as said.
Hmm... I went back and double-checked... you're right. Drawing commands will only take textures up to 1024. I was thinking of sceGuCopyImage() - that's the one that will take any width. So what you need to do is use sceGuCopyImage() to copy 1024xwhatever blocks to your texture storage location, then use that texture with the drawing commands. Sorry about the confusion.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Okay, I'm not doing well today. :)

sceGuCopyImage() only handles widths up to 2047. 2048 or higher has to be handled by hand. I've made a simple png viewer for testing this.

http://www.mediafire.com/download.php?upimlrmpt8y

That's everything but some pngs. :) The main part of the code is the scaling routine which does this:

Code: Select all

void scaleImageToScreen&#40;Image *img&#41;
&#123;
    int BLOCKH = 32;
    int BLOCKV = img->imageHeight <= 512 ? img->imageHeight &#58; img->imageHeight <= 1024 ? img->imageHeight/2 &#58; img->imageHeight <= 2048 ? img->imageHeight/4 &#58; img->imageHeight/8;
    int i, j, ii, jj;
	struct texVertex *vertices;

    sceGuStart&#40;GU_DIRECT,list&#41;;
   	sceGuDisable&#40;GU_BLEND&#41;;

    for &#40;j=0; j<img->imageHeight/BLOCKV; j++&#41;
        for &#40;i=0; i<img->imageWidth/BLOCKH; i++&#41;
        &#123;
            unsigned int ts = &#40;unsigned int&#41;img->data + j * BLOCKV * img->textureWidth * 4 + i * BLOCKH * 4;

            // copy the block to vram
            if &#40;img->textureWidth < 2048&#41;
            &#123;
                sceGuCopyImage&#40;GU_PSM_8888, 0, 0, BLOCKH, BLOCKV, img->textureWidth, &#40;void *&#41;ts, 0, 0, BLOCKH, &#40;void*&#41;&#40;0x44000000 | TEX_BUF&#41;&#41;;
                sceGuTexSync&#40;&#41;;
            &#125;
            else
            &#123;
                for &#40;jj=0; jj<BLOCKV; jj++&#41;
                    for &#40;ii=0; ii<BLOCKH; ii++&#41;
                        *&#40;unsigned int*&#41;&#40;0x44000000 | &#40;TEX_BUF + jj*BLOCKH*4 +ii*4&#41;&#41; = *&#40;unsigned int*&#41;&#40;ts + jj*img->textureWidth*4 +ii*4&#41;;
            &#125;
            sceGuEnable&#40;GU_TEXTURE_2D&#41;;
            sceGuTexMode&#40;GU_PSM_8888,0,0,0&#41;;
            sceGuTexFunc&#40;GU_TFX_REPLACE, GU_TCC_RGB&#41;;
            sceGuTexFilter&#40;GU_LINEAR, GU_LINEAR&#41;;

            // set the texture block
            sceGuTexImage&#40;0, BLOCKH, 512, BLOCKH, &#40;void *&#41;&#40;0x44000000 | TEX_BUF&#41;&#41;;
            sceGuTexSync&#40;&#41;;

            vertices = &#40;struct texVertex*&#41;sceGuGetMemory&#40;2 * sizeof&#40;struct texVertex&#41;&#41;;
            // draw the block with scaling
			vertices&#91;0&#93;.u = 0;
            vertices&#91;1&#93;.u = BLOCKH;

            vertices&#91;0&#93;.v = 0;
            vertices&#91;1&#93;.v = BLOCKV;

            vertices&#91;0&#93;.x = i * BLOCKH * 480 / img->imageWidth;
            vertices&#91;1&#93;.x = &#40;i+1&#41; * BLOCKH * 480 / img->imageWidth;

            if &#40;vertices&#91;1&#93;.x > 480&#41;
                vertices&#91;1&#93;.x = 480;

            vertices&#91;0&#93;.y = j * BLOCKV * 272 / img->imageHeight;
            vertices&#91;1&#93;.y = &#40;j+1&#41; * BLOCKV * 272 / img->imageHeight;

            if &#40;vertices&#91;1&#93;.y > 272&#41;
                vertices&#91;1&#93;.y = 272;

            vertices&#91;0&#93;.z = 0;
            vertices&#91;1&#93;.z = 0;

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

	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0,0&#41;;
   	flipScreen&#40;&#41;;
&#125;
It divides the image both horizontally and vertically to maximize the texture cache, and draws it with scaling one block at a time. The scaling is simply to the size of the LCD for this simple example. It also losses a few pixels off the right side if the png isn't an even multiple of the stripe width (32). It should be enough to show how you do this sort of thing.
Post Reply