#102065 - Moeity - Sun Sep 10, 2006 12:55 pm
I'm making a small ebook app. I'm using a font library to draw antialiased fonts to a buffer image. What is the easiest possible way I can draw two 256*192 uint32 buffers, one to each screen?
So far, I've tried this:
Setting to framebuffer mode, I can draw a page of text to one screen, no problem by writing directly to VRAM_A. For example, when I write a background color to the screen:
videoSetMode(MODE_FB0);
vramSetBankA(VRAM_A_LCD);
for(int i = 0; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++)
VRAM_A[i] = RGB15(BACK_R, BACK_G, BACK_B);
This is very simple, and works fine. I can't seem to get anything to display on both screens though.
Is there a way I can write the same way to the second display? Could I switch the main screen to the bottom display, then call the same code to print to both screens? Or should I be using different video modes entirely?
#102067 - HotChilli - Sun Sep 10, 2006 1:26 pm
RTFM. =) I.e. this manual - http://www.patatersoft.info/manual.html
AFAIU, you should set appropriate memory banks (A, B, C...) for main and sub screens. And write to these memory adresses. In manual above ready demo works with both screens.
#102069 - Sausage Boy - Sun Sep 10, 2006 1:34 pm
While this approach works fine, it's recommended that you use mode 5 and extended rotation backgrounds instead. Why? If you ever want to add more layers, a mouse cursor, debug text or something, you will have to code everything manually if you use the framebuffer. With an extrot bg, you can make the DS's graphics hardware do the work instead.
Anyways, to the implemention. I havn't tested this code, so there might be some minor errors somewhere.
Code: |
vidoeSetMode(MODE_5_2D);
videoSetModeSub(MODE_5_2D); //Set up the sub screen
vramSetBankA(VRAM_A_MAIN_BG); //Use bank a for main screen gfx
vramSetBankC(VRAM_C_SUB_BG); //Use bank c for sub screen gfx
BG3_CR = BG_BMP16_256x256; //Set up our bg's for framebuffer
SUB_BG3_CR = BG_BMP16_256x256;
//Note that the BG is 256 pixels high, but only the first 192 rows are visibe.
//Rotation and scaling stuff. Never mind this. If you want to use it some time, remember that it's fixed point.
BG3_XDX = 1 << 8;
BG3_XDY = 0;
BG3_YDX = 0;
BG3_YDY = 1 << 8;
BG3_CX = 0;
BG3_CY = 0; //This is what we'd change to scroll the background
//and for the sub screen
SUB_BG3_XDX = 1 << 8;
SUB_BG3_XDY = 0;
SUB_BG3_YDX = 0;
SUB_BG3_YDY = 1 << 8;
SUB_BG3_CX = 0;
SUB_BG3_CY = 0;
//Finally, to display stuff...
//Main screen, nice and blue
for(int i = 0; i < 256*256; i++)
BG_GFX[i] = RGB15(0, 0, 31) | BIT(15); //Bit 15 controls transparency, if you leave it out, you'll get a black screen.
//Let's do a green sub screen
for(int i = 0; i < 256*256; i++)
SUB_BG_GFX[i] = RGB15(0, 31, 0) | BIT(15); //DON'T forget bit 15
|
_________________
"no offense, but this is the gayest game ever"
#102237 - Moeity - Tue Sep 12, 2006 3:24 am
Great, both comments were very useful, I have what I wanted working now.
I was confused, and thinking that to use mode 5 I had to have my background as a set of tiles. I didn't realize I could write directly to the screen, and thought you could only do that with the framebuffer. Thanks for clearing that up.
But now I am a little confused... if I can write directly to a layer of a hardware layering mode, what use is the framebuffer mode at all? In what situations would it be preferable to use the framebuffer rather than using a background layer?
#102238 - tepples - Tue Sep 12, 2006 3:42 am
The "extended rotation" modes allow everything that the "framebuffer" mode allows. As far as I can tell, the "framebuffer" mode was added so that GBA mode could use the 2D hardware yet still have a way to translate between the GBA's frame rate (59.7275 Hz) and the DS's (59.8983 Hz), which is a fraction of a percent faster.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#102240 - TJ - Tue Sep 12, 2006 3:49 am
Wait, so you can draw directly on the screen when you aren't in frame buffer mode? I was under the same impression, that you had to specifically be in FB mode to draw primitives on the screen.
#102303 - Lick - Tue Sep 12, 2006 7:53 pm
TJ wrote: |
Wait, so you can draw directly on the screen when you aren't in frame buffer mode? |
Yes!
_________________
http://licklick.wordpress.com
#110124 - mysteryegg - Sat Nov 25, 2006 8:02 pm
For a fancy e-book reader's page flip effect, would it make more sense to animate manually in the frame buffer... or to transfer the contents of the screen to a 3D object and apply the rotating effect there?
For my purposes, actually, I would be happy with a stiff (like cardboard) quad object for the user to scribble on either side for cases like signing the back of a photo or making 2-sided flash cards.
#110126 - tepples - Sat Nov 25, 2006 8:05 pm
If all you need is one quad, you can do that in any mode but 0 by changing the matrix of a rotation layer or extended rotation layer.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#110139 - mysteryegg - Sat Nov 25, 2006 9:54 pm
While that sounds reasonable, all I can figure out how to do with the matrix would be a "squish" or "stretch" effect. What transormation would I need to apply to rotate about the y-axix to introduce some depth?
If this is documented somewhere, point me in the right direction.
#110141 - mysteryegg - Sat Nov 25, 2006 10:31 pm
I had overlooked the GBA discussions on this topic. Looking into TONC now. Hopefully I should be fine...
But for future reference, has anybody made a nice fluid "page flip" effect?
#110149 - Cearn - Sun Nov 26, 2006 12:28 am
Flipping-over effect as seen from an oblique projection. Semi-tested. Apologies for the crummy ascii art.
Code: |
<-- D ->
_________________________
^ |\ | \
| | \ ' \
W | \ / \
| | φ \/_______________________\
v |_.-' ____________________|
r = D/W
Matrix:
A = | 1 r?sin(φ) |
| 0 cos(φ) |
GBA/NDS matrix:
P = A^-1
= | 1 -r?tan(φ) |
| 0 1/cos(φ) |
|
φ is the angle that the page makes with respect to its normal position.
r is an obliqueness ratio, indicating how much you see it from the side. r = 0 would mean you see the page head-on, which wouldn't give much of a flipping effect (boils down to a 1D scaling). Start with, say, r = 0.5 (or -0.5) and fiddle until it looks nice enough.
I'm assuming you're holding the DS vertically here; if not, I think switching the columns of the matrix should suffice. As always, watch your fixed point.