GP2X Larger Frame Buffer


slygamer

Active Member
Joined
Sep 19, 2005
Messages
795
Location
Brisbane, Australia
Website
Visit site
One common method of scrolling in days gone by was to have a frame buffer that larger than the display area. Various registers were set to tell the display which part of the frame buffer to display. In effect, you could get a limited amount of scrolling without redrawing the frame buffer at all.

Can this be done on the GP2X? I've found a register that specifies the horizontal width of the frame buffer, but I'm not sure if this is the right way to do it. Also, I have not found any registers to allow positioning of the display within a frame buffer.
 
If you're talking about what I think you're talking about, it's possible in SDL to have a surface and then blit an SDL_Rect of that surface to the screen. So you could have a frame buffer(ish) larger than the display area.
 
nickspoon: what you proposed is exactly what he wanted to avoid ;)

he wants one big framebuffer and change the base pointer adress for the lcd (so another portion of the framebuffer is displayed).

oh wait.... i guess you'd need to change the pitch too.

i don't know how possible this is (as we afaik use the linux framebuffer device to access the screen). you might have to write a new linux graphics device driver.
 
It seems you can use about 5Mb of memory from 0x03101000 onwards as framebuffer without upsetting any other subsystems. Set the stride (register 0x290C) to the number of bytes to skip to move down to the next line - the same as with the hardware blitter. Then you set registers 0x290e and 0x2912 to the low 16 bits of the 32-bit aligned address of the top left pixel of your screen, and registers 0x2910 and 0x2914 to the high 16 bits. I'm not sure exactly why you set it twice, I think it may have something to do with odd and even scanlines. Note that the address has to be 32-bit aligned, so you can only scroll 4 pixels at a time in 8bpp or 2 pixels at a time in 16bpp.

rlyeh's library uses this for page flipping, switching between the framebuffers of fb0 and fb1, but the concept is still the same if you just ignore the fbdev framebuffers and use memory from 0x03101000 upwards.

Edit: in case you want reference here, I uploaded the latest version of the graphics driver in Allegro. gp2x_gfx_scroll performs the scroll; gp2x_gfx_init sets up the screen according to the user's virtual width/height choices. See from line 520 for using 5Mb of video memory; the stride is calculated on line 547, and put in the right register on line 566. It might be important to reset this on exit - see line 649.

http://www.glost.eclipse.co.uk/gfoot/gp2x/gp2x_gfx.c
 
This is the kind of discussion that these forums should be all about. :)

That is very helpful, gfoot. The odd/even addresses are for setting progressive or interlaced mode. From what I can gather from the Engrish docs, setting them both to the same address tells the display to be displayed in progressive mode. Setting the addresses to be one line apart tells the display to be in interlaced mode.

I should be able to work with this. It's a pity the horizontal offset seems to be limited to 2 or 4 pixels (depending on bpp).
 
One common method of scrolling in days gone by was to have a frame buffer that larger than the display area. Various registers were set to tell the display which part of the frame buffer to display. In effect, you could get a limited amount of scrolling without redrawing the frame buffer at all.

Can this be done on the GP2X? I've found a register that specifies the horizontal width of the frame buffer, but I'm not sure if this is the right way to do it. Also, I have not found any registers to allow positioning of the display within a frame buffer.

This so called "hardware scrolling" is possible but as others said the video pointer can move only by whole 32bit words. Imho it's not big deal anyway - there is demo of smooth moving 8 playfields just using brute force by utilising hardware blitter.

On systems with very limited bandwitch hardware scrolling was mandatory but with more modern machines like gp2x it's not really that usefull.

And hardware scrolling has its disandvanteges too - sprites must have saved backgrounds to be able redraw correctly for next frame. With lots of moving objects it might eat any advantage of hardware scrolling because when you are drawing every frame from start you don't have to deal with it (just one blit is needed for any sprite).

Perhaps by using 2 or 4 (preshifted) surfaces you could scroll smoothly using the video pointer but why?
 
Last edited by a moderator:
It's also possible to "shift" the screen left or right by upto 3 pixels, although this needs either making the screen wider or thinner to accommodate it (else you'll get a white line down the side.) I'm playing around with this as part of trying to get better timings to get rid of scan-lines. Hopefully I'll have it in my next version of SDL.

The shift is the lowest nibble of DPC_DE (0x2826) use 1-3 for shifting right and 8+(1-3) for shifting left (or the other way around.) Don't touch the rest of the register unless you know what you're doing!
 
I had a look at hardware scrolling too.
Unfortunately you only have one scrolling playfield and the frame pointer is the same for all regions.
For arcade game style scrolling I think you're best off using the blitter for your playfields and sprites redrawing the screen each time. The blitter can easily manage this.
You can still use the frame pointer for page flipping and also for applying screen shake effects etc.
You could do some interesting stuff if you get a horizontal interrupt handler going on and split the screen into horizontal sections.
Also you could do a sort of guard band clip with the blitter by creating a frame buffer larger than the screen and set the display pointer to point to the centre of the screen. If the border was 64 pixels all around then you'd only need to clip images larger than 64x64. It's a bit wastful of memory I know but the GP2X has got tons of memory!
 
I had a look at hardware scrolling too.
Unfortunately you only have one scrolling playfield and the frame pointer is the same for all regions.

Still it's much better than not having playfields at all. I can imagine they would be very usefull for such things like cocpits, game's scores/energy display and faster sprites (blitter can clear them using only solid fill - big save on blitts).
 
Last edited by a moderator:
Indeed, for example I found the GP32 to be easily fast enough to redraw its full screen several time (in 8bpp) in one frame... Bolcataxian for instance was dual scrolling, starfield, loads of particles, fonts, plenty of sprites & their shadows, highlights etc... all pixel by pixel pokes on the frame buffer & a few blits.

Unfortunately, on Gp2x, it's not quite as fast yet, as least for me... SDL under linux seems fairly significanly slower than the GP32 (clocked at 133Mhz) with its normal sdk, and I run in two frames from the moment. Can't wait for hardware accelerated SDL to kick in!

Cheerio,
JBB
 
I've now got pixel-perfect hardware scrolling implemented, but the side effect is the one that paeryn mentioned (the vertical line on the edge of the screen, which in my case is bright green). I've got a 480x480 buffer scrolling around quite nicely, bar the bright green line.
 
I've now got pixel-perfect hardware scrolling implemented, but the side effect is the one that paeryn mentioned (the vertical line on the edge of the screen, which in my case is bright green). I've got a 480x480 buffer scrolling around quite nicely, bar the bright green line.
Since you've got space on the right you can just make the screen say 324 pixels wide (0x2816), as long as you don't extend it too far you shouldn't have any (serious) timing issues. Only works on left-shifting (line down the right)
 
Last edited by a moderator:
Setting the screen width to 324 (or 322 or 328) simply makes the bright green line become a black line. It seems that you cannot have a shift of +1 and have a column of pixels in the far-right column on the screen. It is a lot less noticeable with the line being black instead of green, and some people may not care about it.
 
Back
Top