forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Image Scaling Algorithm with pg.c/.h?

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
seventoes



Joined: 02 Oct 2005
Posts: 79

PostPosted: Sun Dec 04, 2005 6:57 am    Post subject: Image Scaling Algorithm with pg.c/.h? Reply with quote

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
View user's profile Send private message
Brunni



Joined: 08 Oct 2005
Posts: 186

PostPosted: Sun Dec 04, 2005 7:50 am    Post subject: Reply with quote

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
View user's profile Send private message
urchin



Joined: 02 Jun 2005
Posts: 121

PostPosted: Sun Dec 04, 2005 8:24 am    Post subject: Reply with quote

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
View user's profile Send private message
seventoes



Joined: 02 Oct 2005
Posts: 79

PostPosted: Sun Dec 04, 2005 8:33 am    Post subject: Reply with quote

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
View user's profile Send private message
Brunni



Joined: 08 Oct 2005
Posts: 186

PostPosted: Sun Dec 04, 2005 9:19 am    Post subject: Reply with 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);
_________________
Sorry for my bad english
Oldschool library for PSP - PC version released
Back to top
View user's profile Send private message
seventoes



Joined: 02 Oct 2005
Posts: 79

PostPosted: Wed Dec 07, 2005 11:07 am    Post subject: Reply with quote

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
View user's profile Send private message
dr_watson



Joined: 28 Nov 2005
Posts: 42

PostPosted: Wed Dec 07, 2005 12:39 pm    Post subject: Reply with quote

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
View user's profile Send private message
seventoes



Joined: 02 Oct 2005
Posts: 79

PostPosted: Thu Dec 08, 2005 5:35 am    Post subject: Reply with quote

Thanks! The function worked brunni!

Ill take a look at your JGE thingy when i get home, im at school now.
Back to top
View user's profile Send private message
dr_watson



Joined: 28 Nov 2005
Posts: 42

PostPosted: Thu Dec 08, 2005 10:02 am    Post subject: Reply with quote

You may like to grab the JGE source from here again, together with the source code of a game prototype (StarBugz) as well.
http://forums.ps2dev.org/viewtopic.php?t=4286
Back to top
View user's profile Send private message
seventoes



Joined: 02 Oct 2005
Posts: 79

PostPosted: Thu Dec 08, 2005 11:22 am    Post subject: Reply with quote

Thanks for the engine watson. I dont really understand C++, but ill try and work with it.
Back to top
View user's profile Send private message
rinco



Joined: 21 Jan 2005
Posts: 255
Location: Canberra, Australia

PostPosted: Thu Dec 08, 2005 6:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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