 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sat Aug 09, 2008 2:21 am Post subject: 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/~sauronlenoir/psppdf_preview.zip
and for the fat
http://www.enterinmydream.info/~sauronlenoir/psppdf_preview_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 |
|
| Back to top |
|
 |
pspZorba
Joined: 22 Sep 2007 Posts: 156 Location: NY
|
Posted: Sat Aug 09, 2008 3:39 am Post subject: |
|
|
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 ! |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sat Aug 09, 2008 4:10 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sat Aug 09, 2008 4:41 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Sat Aug 09, 2008 6:10 am Post subject: |
|
|
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;" |
|
| Back to top |
|
 |
pspZorba
Joined: 22 Sep 2007 Posts: 156 Location: NY
|
Posted: Sat Aug 09, 2008 6:31 am Post subject: |
|
|
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 ! |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sat Aug 09, 2008 6:58 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sat Aug 09, 2008 11:02 am Post subject: |
|
|
| 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 |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sun Aug 10, 2008 12:23 am Post subject: 10000000000 |
|
|
| 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 |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Aug 10, 2008 3:33 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Aug 10, 2008 4:09 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Sun Aug 10, 2008 4:48 am Post subject: |
|
|
| 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: |
sceGuTexImage(0, MIN(512,img->stride), MIN(512,img->tex_height), img->stride, img->data);
|
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 |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Aug 10, 2008 6:02 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Aug 10, 2008 6:14 am Post subject: |
|
|
| 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: |
sceGuTexImage(0, MIN(512,img->stride), MIN(512,img->tex_height), img->stride, img->data);
|
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. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Aug 10, 2008 7:34 am Post subject: |
|
|
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: | 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();
} |
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. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|