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 

tile engine help

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



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 7:28 am    Post subject: tile engine help Reply with quote

hey..im starting a psp tile 2d scroller..and well i have my "map" as a 2d array

60x30 integers.. where each tile is 16x16 pixels.

so the map is 960x 480 pixels (bigger than the psp screen..which is what i want)

so i have this big map, and then i have a viewable area (the psp screen) which will be 29 x 17 tiles, where each tile is 16x 16

so i have a global int mapX and mapY, which increment the top-left of where i should start drawing from on the BIG map..

so i have the D-Pad changing the mapX and mapY values..

then in my drawMap function..

i find out which tile based on mapX and mapY will be the top left on the psp screen

tileX=mapX /16
tileY=mapY/16

pretty straight foward so far..

so then i pgBitBlt the tiles that are visible on the screen...and when i press the D-Pad i scroll through my map just fine..

however, i have my mapX and mapY being incremented by 16.. the size of a tile.. so that works out just fine..

but if I want to have smooth scrolling..i need to increment by less than the size of a tile...this is where my problem comes into play..

so say i increment by 5..that means ill have to draw only part of a tile on the right side of the screen..not a full tile..

however, on the psp..if you bitblt anything off the x/y of the screen..it freezes up...

i probably lost you by now..so ill paste some of my code..so you can see it..


//This is how i change the mapX and mapY values with the DPAD

case 5: //UP ARROW
if(mapY-16 > MAP_MIN_Y)
{
mapY-=16;
}
break;

case 6://DOWN ARROW
if(mapY+16 < MAP_MAX_Y)
{
mapY+=16;
}
break;

case 7://LEFT ARROW
if(mapX-16 > MAP_MIN_X)
{
mapX-=16;
}
break;

case 8://RIGHT ARROW
if(mapX+16 < MAP_MAX_X)
{
mapX+=16;
}




//


void drawMap(int drawX,int drawY)
{

int tileX = drawX/16;
int tileY = drawY/16;



int x,y;
for(x=0;x<29;x++)
{
for(y=0;y<17;y++)
{

drawTile(map[tileY+y][tileX+x].tile_number,x*16,y*16);

}
}

}

void drawTile(int tileNum,int X,int Y)
{


switch(tileNum)
{
case 0:
pgBitBlt(X,Y,TILE_WIDTH,TILE_HEIGHT,1,image_grass);
break;

case 1:
pgBitBlt(X,Y,TILE_WIDTH,TILE_HEIGHT,1,image_dirt);
break;

case 2:
pgBitBlt(X,Y,TILE_WIDTH,TILE_HEIGHT,1,image_water);
break;
}


}
Back to top
View user's profile Send private message
inomine



Joined: 05 May 2005
Posts: 53

PostPosted: Thu Jun 23, 2005 8:22 am    Post subject: Re: tile engine help Reply with quote

JJPeerless wrote:


however, on the psp..if you bitblt anything off the x/y of the screen..it freezes up...



Well, depending on where exactly, but yes it will if you try to write to some place that you shouldn't. So what you need to do is write some code to make sure that you don't :P
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 8:46 am    Post subject: Reply with quote

if you provide a range check in bitblit to see if the x,y values of the pixel to be written are valid, you can make it work.. it might make it slower, and there is almost certainly a way to optimise(sp?) this, but it will work. ie:

Code:

void pgRangeBitBlt(unsigned long x,unsigned long y,unsigned long w,unsigned long h,unsigned long mag,const unsigned short *d)
{

unsigned long xloop,yloop,ymag,xmag;
const unsigned short *dd;
unsigned char *vptr0; //vram pointer

for (yloop=y; yloop<y+h; y++)
{
  for (ymag=0; ymag<mag; ymag++)
  {
    dd=d;
    for (xloop=x; xloop<x+h; x++)
    {
      for (xmag=0; xmag<mag; xmag++)
      {
        if ((xloop >=0) && (x < SCREEN_WIDTH) && (y>= 0) && (y < SCREEN_HEIGHT))
         {
           vptr0=pgGetVramAddr(xloop+xmag,yloop+ymag);
           *(unsigned short *)vptr0=*dd;
         }
      }
       dd++;
    }
  }
   d+=w;
}
}


note.. this may not work.. i have not tested it yet, but even if it doesn't, it will give you a platform to start from.. happy coding!

[EDIT] I forgot a semicolon after vptr0's declaration.. whoops..
seems it will compile now, but the logic might be a bit flawed, so use with care


Last edited by wulf on Thu Jun 23, 2005 9:18 am; edited 1 time in total
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 8:51 am    Post subject: Reply with quote

the main problem is i dont understand how nem's pg libary actually works..i only know how to USE it..

i dont understand any of the primitive functions of the psp that he is using in his functions..

but all your doing is..as it loops through each pixel of the picture..if the coords of it are not within the screen bounds..your just not drawing it..right?
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 8:51 am    Post subject: Reply with quote

what about..drawing the image thats bigger than the screen to a bufffer..then clipping it to the correct size and then flip that to the screen.. would that be any more efficient?
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 9:00 am    Post subject: Reply with quote

well, I don't know, but I don't think so, because in the end, you have to write the data twice..
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 9:02 am    Post subject: Reply with quote

note that mag's lowest value is 0, so if you call it with mag=1, your tiles will be twice their orig size.. (just noticed that bug)
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 9:30 am    Post subject: Reply with quote

i think my confusion is actually going back to plain old C...

i dont understand unsigned char...doesnt it only hold a byte from 0-255...

how can an unsigned char be the "vram" or whatever..i dont understand

char *pg_vramtop=(char *)0x04000000;

like that..
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 10:04 am    Post subject: Reply with quote

because it is the color information...
the address is held in the pointer, but the pointer points to an unsigned char, which is the color..
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 12:23 pm    Post subject: Reply with quote

yea..but its ONE char... isnt the screen made up of like hmm.. 480 x 272 pixels..
shouldnt it be a 2d array of chars?
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 12:32 pm    Post subject: Reply with quote

ahh, see, that's the trick... you only need access to the first char, then you offset the pointer by the size of exactly one char for each pixel into the picture you want.. note that to move down a y value, you have to offset by y*SCREEN_WIDTH because you are "skipping" those pixels.

and that makes me think that I have another bug in my function.. hold on

... no not the one I thoght... nm
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 12:35 pm    Post subject: Reply with quote

ok well, thats what i figured..

so say the screen looks like this:

011100
111111
111000
111111

then in memory it would be

011100111111111000111111

and the char points to the first 0..and you just increase your position to go through the bytes?
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 12:40 pm    Post subject: Reply with quote

maybe I should have said :

althogh your picture is 2d, all memory (on your hdd, the psp, everything) is 1d

that means that your pic must be chopped up and arranged in mem as 1d, then when the psp puts it on screen, it reads out the 1d memory in chunks of SCREEN_WIDTH, for each line.

so like this for a 4x3 "pic" alternating blue and red stripes:

blue blue blue blue
red red red red
blue blue blue blue

/\ this is how you see it when you edit it in image editor..

\/ but this is how it's saved:

blue blue blue blue red red red red blue blue blue blue

AND, that's how the psp's memory needs to look when you put the pic on the screen..

that's what the loops do.. they shuffle through the picture aligning the psp's memory and the stored pic, and then copying over the pic, one pixel at a time.
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 12:41 pm    Post subject: Reply with quote

ok, that's just too funny! you totally got it, though..:)
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 12:53 pm    Post subject: Reply with quote

vptr0=pgGetVramAddr(x,y);

what is that doing..before all the loops

the loop makes no sense to me..it doesnt "save" anything anywhere..it just adds stuff to those vptr and vptr0..which i dont understand either..
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 2:41 pm    Post subject: Reply with quote

vptr0 is just a pointer to the vram of the psp..
pgGetVramAddr supplies the correct address for a given pixel for each iteration.
the next line puts the pixel data from the picture into the ram, effectively drawing one pixel..

jeach time the for loops are incremented, the yloop and xloop values change.
that means that as the loop progresses, the place in ram, and the place in the image are being
changed. that way, the line
*(unsigned short *)vptr0=*dd; (which is the pixel writing line)
is always writing to a different place, from a different place.
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 2:46 pm    Post subject: Reply with quote

how can i go about having another buffer, that is slightly wider than the actual psp screen..then use a function almost identical to bitblt to write this "bigger buffer"..like at top will i need to do something like

char *pg_vramtop2=(char *)0x04000000; and change the offset?

and then write to that using the new bitblt..

and then i want to be able to take that new buffer..and not start from 0,0 and go to 480x 272..but go from some xOff,yOff to xOff+482, yOff+272..

but i dont know how to create such a buffer..or copy a 480x272 portion of the new buffer to the main buffer..
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 2:47 pm    Post subject: Reply with quote

or do you mean the original bitblit from pg.c?

cause i thought you were talking about my code..
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Thu Jun 23, 2005 2:50 pm    Post subject: Reply with quote

im still talking about the original..
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 4:04 pm    Post subject: Reply with quote

oh, I see.

well, his style is a bit different than mine, but i wrote mine based on his...
his variable naming is a bit hard to understand at first, that's why I changed the names of mine..

but the basic premise is this..
he gets the place of the first pixel in the psp's ram with the vptr0=... line
he increments the place in memory with the vptr+=PIXELSIZE*2; command
and the vptr0+=LINESIZE*2; command, instead of using vptr0=pgGetVramAddr(x,y);
for every pixel, like I do..
his way is faster, but it means that since you are blindly incrementuing the position in memory,
you can easily run out of the valid memory..
he needs two of each variable (xx,yy,vptr0,vptr,etc) because of the built in magnification he wrote. that's because of the way the magnification works: it simply moves the ram address without moving the part of the picture it's drawing, so each pixel gets doubled up,(or tripled, or whatever)

the reason for the doubling up of the variables is because there needs to be a way to "uncouple" the picture incrementing while the magnification code is being implemented.
here is some pseudocode for what is basically happening:
the doubling of variables basically allows us to "remember" where we were before the magnification part took place (rewind to before it)

Code:

loop through y values of picture
           loop through the magnification of y
                   make a copy of the vram position so the mag doesn't screw us up
                    make a copy of the picture pos for the same reason
                      loop through the x values of the picture (master x loop)
                              loop through the mag of x
                                     draw the pixel
                                     go to the next place in vram
                              end of magx loop
                              go to the next pixel(x)
                     end of master x loop
                     go to the next line in vram
           end of magy loop
           go to the next line in picture(y)
end of master y loop


you can also use the above for comments on each line below.

btw, understanding exactly how it works isn't ultra-mega-super important, as long as you get the gist..
you just have to be able to implement it in your code..
and you will understand it, if you keep trying.
another place that will help you with game drawing stuff is www.gamedev.org (or is it .com?)
you will find that pretty much all pixel/picture drawing routines similar, regardless of the platform..
the only code here that is psp specific is the function that determines the correct address in ram, getVramAddr..

Code:

void pgBitBlt(unsigned long x,unsigned long y,unsigned long w,unsigned long h,unsigned long mag,const unsigned short *d)
{
   unsigned char *vptr0;      //pointer to vram
   unsigned char *vptr;      //pointer to vram
   unsigned long xx,yy,mx,my;
   const unsigned short *dd;

   vptr0=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++) {
               *(unsigned short *)vptr=*dd;
               vptr+=PIXELSIZE*2;
            }
            dd++;
         }
         vptr0+=LINESIZE*2;
      }
      d+=w;
   }

}
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Thu Jun 23, 2005 4:21 pm    Post subject: Reply with quote

to be honest, I'm not exactly sure about your "bigger buffer" question.. I assume you want to keep it in Vram?

if you don't, then you could make an array with the same number of elements as pixels for your buffer,
copy the image data into this array, then use a modified bitblt to only capture the data you want.

you would need to add some paramaters to the bitblt function, like xoffset, yoffset, and possibly xlength and ylength values if you wanted to have a variable "window"

you would also need code to set the position in bigbuffer to the right place at the start, and then
set it again to the proper offset inside your bigbuffer every new line..

you would then repeat this until your psp-screen-sized window is copied into vram.

sorry if this isn't making any sense, but It's late here, and I'm pretty tired..
hope this helps,
wulf
Back to top
View user's profile Send private message
JJPeerless



Joined: 20 Jun 2005
Posts: 82

PostPosted: Fri Jun 24, 2005 3:48 am    Post subject: Reply with quote

i just want to thank you wulf..for your time..

i actually understand what nem's graphics library does now..and i was able to rewrite the functions i need..and i got my tile problem working!

thanks alot!
Back to top
View user's profile Send private message
wulf



Joined: 13 Apr 2005
Posts: 81

PostPosted: Fri Jun 24, 2005 8:14 am    Post subject: Reply with quote

Sweet! I'm glad I could help.. to be honest, I learned a lot too... before seeing nem's code, I had no idea how to implement a magnification for sprites.. :P but anyway, you're welcome.
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