 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
seventoes
Joined: 02 Oct 2005 Posts: 79
|
Posted: Sun Dec 04, 2005 6:57 am Post subject: Image Scaling Algorithm with pg.c/.h? |
|
|
Hey im back with another algorithm problem xD
This time i need something to scale the 16 bit image. I have absolutely no idea how to do this... and i've tried using google but cant seem to get any good results.
I am using pc.c/.h to blit my pictures (I would use the GU but i dont get it..) and i have already added alpha blending as an extra argument. Heres my function right now:
| Code: |
#define rgb2col(r, g, b) ((((b>>3) & 0x1F)<<10)+(((g>>3) & 0x1F)<<5)+(((r>>3) & 0x1F)<<0)+0x8000)
#define getR( c ) ( (c & 0x1f) << 3 )
#define getG( c ) ( ((c >> 5) & 0x1f ) << 3 )
#define getB( c ) ( ((c >> 10) & 0x1f) << 3 )
...
void pgBitBlt(unsigned long x,unsigned long y,unsigned long w,unsigned long h,unsigned long mag,const unsigned short *d, int t)
{
unsigned char *vptr0; //pointer to vram
unsigned char *vptr; //pointer to vram
unsigned long xx,yy,mx,my;
const unsigned short *dd;
int rB, gB, bB, rS, gS, bS, new_r, new_g, new_b; //color thingys
vptr0=(unsigned)pgGetVramAddr(x,y);
for (yy=0; yy<h; yy++) {
for (my=0; my<mag; my++) {
vptr=vptr0;
dd=d;
for (xx=0; xx<w; xx++) {
for (mx=0; mx<mag; mx++) {
if (*dd != 0x3e0) {
if (t != 255) {
rB = getR(*(unsigned short *)vptr);
gB = getG(*(unsigned short *)vptr);
bB = getB(*(unsigned short *)vptr);
rS = getR(*dd);
gS = getG(*dd);
bS = getB(*dd);
new_r = rB + (((rS - rB) * t) / 256);
new_g = gB + (((gS - gB) * t) / 256);
new_b = bB + (((bS - bB) * t) / 256);
*(unsigned short *)vptr = rgb2col(new_r,new_g,new_b);
}
else {
*(unsigned short *)vptr = *dd;
}
}
vptr+=PIXELSIZE*2;
}
dd++;
}
vptr0+=LINESIZE*2;
}
d+=w;
}
}
|
How could i add a scaling factor to the function? |
|
| Back to top |
|
 |
Brunni
Joined: 08 Oct 2005 Posts: 186
|
Posted: Sun Dec 04, 2005 7:50 am Post subject: |
|
|
Speaking about algorithm only, scaling is very simple. In 32 bits without conversion it would look like this:
spr: sprite (32-bit pixels)
vptr: vram (32-bit pixels, LARG_BUF is buffer line width, LARG=width, HAUT=height)
x0, y0: drawing coordinates
lb, hb: base width (l), height (h)
l, h: new width and height
I've not tested it, but this gives you an idea.
| Code: | #define VIRGULE 16
void Rescale(unsigned short *spr, unsigned short *vptr, int x0, int y0, int lb, int hb, int l, int h) {
int x, y;
unsigned short *bits=vptr, *ptr, *spr2, *sprite;
int y_min, x_min, y_max, x_max;
long scaleX, scaleY, dstX, dstY;
int x1=x0+l, y1=y0+h;
//Clipping
if (x0>=0) x_min=x0;
else x_min=0;
if (y0>=0) y_min=y0;
else y_min=0;
if (x1<LARG) x_max=x1;
else x_max=LARG;
if (y1<HAUT) y_max=y1;
else y_max=HAUT;
scaleX=(lb<<VIRGULE)/l;
scaleY=(hb<<VIRGULE)/h;
dstY=scaleY*(y_min-y0);
for (y=y_min;y<y_max;y++) {
ptr=bits+LARG_BUF*y+x_min;
spr2=spr+lb*(dstY>>VIRGULE);
dstX=scaleX*(x_min-x0);
dstY+=scaleY;
for (x=x_min;x<x_max;x++) {
sprite=spr2+(dstX>>VIRGULE);
dstX+=scaleX;
if (*sprite==COLOR_TRANSPARENT) {
sprite++;
ptr++;
continue;
}
*ptr++=*sprite++;
}
}
} |
_________________ Sorry for my bad english
Oldschool library for PSP - PC version released
Last edited by Brunni on Sun Dec 04, 2005 9:20 am; edited 2 times in total |
|
| Back to top |
|
 |
urchin
Joined: 02 Jun 2005 Posts: 121
|
Posted: Sun Dec 04, 2005 8:24 am Post subject: |
|
|
| Take a look at the sprites example in the SDK. Blitting and scaling a rect using GU is very easy. You get the option of filtering too. |
|
| Back to top |
|
 |
seventoes
Joined: 02 Oct 2005 Posts: 79
|
Posted: Sun Dec 04, 2005 8:33 am Post subject: |
|
|
| That might work, but what are LARG and HAUT? And would that work with 16 bit images? because thats what im using. |
|
| Back to top |
|
 |
Brunni
Joined: 08 Oct 2005 Posts: 186
|
Posted: Sun Dec 04, 2005 9:19 am Post subject: |
|
|
I changed the routine in my last post. With this one, it might work in 16-bit mode. LARG is the width of your sprite, and HAUT the height.
Typical 2x scaling for a 16x16 sprite on a 480x272 buffer (buffer width aligned to 512):
#define LARG 480
#define HAUT 272
#define LARG_BUF 512
Rescale(mysprite, myvideobuffer, 0, 0, 16, 16, 32, 32); _________________ Sorry for my bad english
Oldschool library for PSP - PC version released |
|
| Back to top |
|
 |
seventoes
Joined: 02 Oct 2005 Posts: 79
|
Posted: Wed Dec 07, 2005 11:07 am Post subject: |
|
|
| urchin wrote: | | Take a look at the sprites example in the SDK. Blitting and scaling a rect using GU is very easy. You get the option of filtering too. |
I've tried that, but i just dont get it. If someone could write a SIMPLE example, maybe functions like gu_init(); or something...
| Quote: |
I changed the routine in my last post. With this one, it might work in 16-bit mode. LARG is the width of your sprite, and HAUT the height.
Typical 2x scaling for a 16x16 sprite on a 480x272 buffer (buffer width aligned to 512):
#define LARG 480
#define HAUT 272
#define LARG_BUF 512
Rescale(mysprite, myvideobuffer, 0, 0, 16, 16, 32, 32); |
Thanks, im trying that now. |
|
| Back to top |
|
 |
dr_watson
Joined: 28 Nov 2005 Posts: 42
|
Posted: Wed Dec 07, 2005 12:39 pm Post subject: |
|
|
Grab a copy of my little 2D game engine JGE (together with a small demo) and have a look of the related Gfx_RenderQuad() function. It uses Gu library for image rendering.
Engine source
And firmware 1.50 binary:
(You also need libpng and mikmodlib to build)
I'm still cleaning up the code and will do a "formal" posting at this forum soon, but at the meantime, you can check out the source and hope it can give you some hints :) |
|
| Back to top |
|
 |
seventoes
Joined: 02 Oct 2005 Posts: 79
|
Posted: Thu Dec 08, 2005 5:35 am Post subject: |
|
|
Thanks! The function worked brunni!
Ill take a look at your JGE thingy when i get home, im at school now. |
|
| Back to top |
|
 |
dr_watson
Joined: 28 Nov 2005 Posts: 42
|
|
| Back to top |
|
 |
seventoes
Joined: 02 Oct 2005 Posts: 79
|
Posted: Thu Dec 08, 2005 11:22 am Post subject: |
|
|
| Thanks for the engine watson. I dont really understand C++, but ill try and work with it. |
|
| Back to top |
|
 |
rinco
Joined: 21 Jan 2005 Posts: 255 Location: Canberra, Australia
|
Posted: Thu Dec 08, 2005 6:47 pm Post subject: |
|
|
| SDL_rotozoom.c (part of SDL_gfx) can also stretch (and rotate). Currently it does not use any Gu functions, but it might one day. |
|
| 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
|