Preview of pdf reader for psp
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
Preview of pdf reader for psp
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
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.
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
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
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
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
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
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.
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
Why don't you use PSP_HEAP_SIZE_MAX? It will already allocate max memory in both.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
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;"
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
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
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
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.sauron_le_noir wrote: tri was better than oslib (limitation on bitmap 512x512) but cannot render bitmap higher than 1024x1024
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
10000000000
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.Raphael wrote: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.sauron_le_noir wrote: tri was better than oslib (limitation on bitmap 512x512) but cannot render bitmap higher than 1024x1024
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
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
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.
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.
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.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.
Just so we're in sync:
Code: Select all
sceGuTexImage(0, MIN(512,img->stride), MIN(512,img->tex_height), img->stride, img->data);
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
-
- Posts: 203
- Joined: Sat Jul 05, 2008 8:03 am
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
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
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.Raphael wrote: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.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.
Just so we're in sync:That's where I set the stride, but this behaves as said.Code: Select all
sceGuTexImage(0, MIN(512,img->stride), MIN(512,img->tex_height), img->stride, img->data);
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:
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.
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(Image *img)
{
int BLOCKH = 32;
int BLOCKV = img->imageHeight <= 512 ? img->imageHeight : img->imageHeight <= 1024 ? img->imageHeight/2 : img->imageHeight <= 2048 ? img->imageHeight/4 : img->imageHeight/8;
int i, j, ii, jj;
struct texVertex *vertices;
sceGuStart(GU_DIRECT,list);
sceGuDisable(GU_BLEND);
for (j=0; j<img->imageHeight/BLOCKV; j++)
for (i=0; i<img->imageWidth/BLOCKH; i++)
{
unsigned int ts = (unsigned int)img->data + j * BLOCKV * img->textureWidth * 4 + i * BLOCKH * 4;
// copy the block to vram
if (img->textureWidth < 2048)
{
sceGuCopyImage(GU_PSM_8888, 0, 0, BLOCKH, BLOCKV, img->textureWidth, (void *)ts, 0, 0, BLOCKH, (void*)(0x44000000 | TEX_BUF));
sceGuTexSync();
}
else
{
for (jj=0; jj<BLOCKV; jj++)
for (ii=0; ii<BLOCKH; ii++)
*(unsigned int*)(0x44000000 | (TEX_BUF + jj*BLOCKH*4 +ii*4)) = *(unsigned int*)(ts + jj*img->textureWidth*4 +ii*4);
}
sceGuEnable(GU_TEXTURE_2D);
sceGuTexMode(GU_PSM_8888,0,0,0);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
sceGuTexFilter(GU_LINEAR, GU_LINEAR);
// set the texture block
sceGuTexImage(0, BLOCKH, 512, BLOCKH, (void *)(0x44000000 | TEX_BUF));
sceGuTexSync();
vertices = (struct texVertex*)sceGuGetMemory(2 * sizeof(struct texVertex));
// draw the block with scaling
vertices[0].u = 0;
vertices[1].u = BLOCKH;
vertices[0].v = 0;
vertices[1].v = BLOCKV;
vertices[0].x = i * BLOCKH * 480 / img->imageWidth;
vertices[1].x = (i+1) * BLOCKH * 480 / img->imageWidth;
if (vertices[1].x > 480)
vertices[1].x = 480;
vertices[0].y = j * BLOCKV * 272 / img->imageHeight;
vertices[1].y = (j+1) * BLOCKV * 272 / img->imageHeight;
if (vertices[1].y > 272)
vertices[1].y = 272;
vertices[0].z = 0;
vertices[1].z = 0;
sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D, 2,0,vertices);
}
sceGuFinish();
sceGuSync(0,0);
flipScreen();
}