synkro
0xdeadbeef
Code:
/*
* GP32 Tutorial 02 "Doube Buffering"
*
* Intro
* -----
* This time we learn something about double buffering, an essential
* technique. The idea is that instead of drawing directly on the screen
* you just show an already "rendered" frame while we work on the next. After
* drawing on the second framebuffer we flip both showing the second one and
* and drawing on the first. Double buffering prevents the screen from flickering.
*
* Let's bring it on!
* ------------------
* 0. #define WIDTH 320
* This statement allows you to set up macro definitions. The word
* immediately after the #define, together with its arguments, is
* expanded in the program text to the whole of the rest of the line.
* In this case WIDTH will be replaced with 320. Keep on mind that WIDTH
* is not a variable.
*
* 1. unsigned short *framebuffer2;
* We want to use two framebuffers this time so we have to declare two
* pointers and point them to framebuffer data elements. unsigned short
* some kind of a smaller integer.
*
* 2. framebuffer2 = (unsigned short*) (FRAMEBUFFER + (WIDTH*HEIGHT*2));
* we point framebuffer1 to the primary FRAMEBUFFER. We also have to
* to point framebuffer2 next to the first framebuffer. But how to
* calculate the size of a framebuffer? We need this as an offset to
* determine where the second framebuffer begins.
* The screen resolution is 320x240 pixel. We are using the 16bit mode,
* so every pixel has 16bit color depth. The memory is aligned bytewise,
* so we need 16bit = 2byte per pixel. That makes 320*240*2 bytes for a
* framebuffer.
*
* 3. gp_SetView(framebuffer1);
* To make a framebuffer visible on screen we use this function, it needs
* a pointer to a framebuffer as argument. As long as we a are showing the
* first framebuffer we can do with the second what ever we want.
*
* 4. gp_SetFont8(30, 110, 20, "This is framebuffer2", 0xF800, framebuffer2);
* This line draws red text on framebuffer2 at (30,110), but why is the
* text red? We know that every pixel has 16bit color depth
* (RRRRRGGGGGBBBBB0 = 16 bit) the first five bits are red the next five
* bits are green and the next blue. The last bit is unused.
* For red you need 1111 1000 0000 0000 = 0xF800, that's all!
*
* 5. for (i=0; i<9000000; i++) i=i;
* This for loop does nothing but wasting time, this is a very ugly way to
* make the GP32 wait for a moment. We will later learn how to use timers.
* The for loop runs as long as the condition (i<9000000) is true. This is
* a really ulgy way to do that, the GP32 offers a real time clock for this.
*
* Oh boy! We learned a thing this time. Again try to re-type the following
* code and try to understand it. As you know it does not make any sense
* if you cheat yourself with copy and paste. This tuto was rather short but
* double buffering is so essential it needs its own chapter. I guess that
* you still don't understand what pointers really are. I will explain this
* painfull topic in one of the next tutos, till then try this:
* A) Instead of adding the text directly in the SetFont8 function,
* try to use a char array (char []) like in chapter one.
* B) Look up any SDK function used in this and in the last tutorial in the
* SDK manual.
* C) Give framebuffer1 a red and framebuffer2 a blue background.
*
* Disclaimer
* ----------
* This Tutorial is based on Mr. Mirko's SDK (mirko@mirkoroller.de)
* download it at: http://home.t-online.de/home/mirkoroller/gp32/
* THIS TUTORIAL IS NOT WRITTEN BY MR. MIRKO! Parts of this Tutorial
* are from the SDK examples or manual.
* If you have any questions on this please try first to get the needed
* info on www.gp32x.de or #gp32dev (EFNET) before contacting the author.
*
* SDK by Mr. Mirko mirko@mirkoroller.de
* Tutorial by synkro synkro@gmx.net
* 26.04.2004 14:19:21
*/
#include <gp32.h>
#define WIDTH 320 // We don't have to remember this all the time
#define HEIGHT 240 // when we defined it once.
unsigned short *framebuffer1;
unsigned short *framebuffer2;
// We declare two framebuffer pointers
int main(void)
{
int i;
framebuffer1 = (unsigned short*) FRAMEBUFFER;
// This sets the framebuffer1 pointer to 0x0C7B4000, the
// start of the memory area for the screen.
framebuffer2 = (unsigned short*) (FRAMEBUFFER + (WIDTH*HEIGHT*2));
// A framebuffer has a size of 320*240*2 bytes. This is the
// offset we add to the primary framebuffer.
gp_SetScreen(framebuffer1,16);
// We only have to set the primary framebuffer into 16bit mode.
for (i=0; i<WIDTH*HEIGHT; i++) // this for loops goes through all pixel
{ // on a framebuffer.
framebuffer1[i] = 0xFFFF; // Sets the i-th pixel white on framebuffer1
framebuffer2[i] = 0xFFFF; // this does the same with framebuffer2
}
gp_SetCpuSpeed(66);
while (1)
{
gp_SetView(framebuffer1);
// Display of framebuffer1
for (i=0; i<WIDTH*HEIGHT; i++) framebuffer2[i] = 0xFFFF;
// Clear framebuffer2
gp_SetFont8(30, 110, 20, "This is framebuffer2", 0xF800, framebuffer2);
// Drawing text on framebuffer2
for (i=0; i<9000000; i++) i=i;
// This is a waiting loop. We need this because the GP32
// would change the framebuffers too fast. We would see
// it only flickering.
gp_SetView(framebuffer2);
// Display of framebuffer2
for (i=0; i<WIDTH*HEIGHT; i++) framebuffer1[i] = 0xFFFF;
// Clear framebuffer1
gp_SetFont8(30, 100, 20, "This is framebuffer1", 0xF800, framebuffer1);
// Drawing text on framebuffer1
for (i=0; i<9000000; i++) i=i;
}
}
Last edited by a moderator: