Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Page flipping with timers

Credits go to Christopher Bludau and miran for helping out!
This thread is locked; no one can reply to it. rss feed Print
Page flipping with timers
Brian Simpson
Member #6,645
December 2005
avatar

I'm currently using page flipping with my new project, but it has a few problems. It flickers occasionally and I don't think I'm doing it correctly. I'm using an accurate timer richard phillps(sp?) gave to me as well.

1 //Called in initalization
2 page1 = create_video_bitmap(SCREEN_W, SCREEN_H);
3 page2 = create_video_bitmap(SCREEN_W, SCREEN_H);
4 activepage = page2;
5 rectfill(page1, 0, 0, page1->w, page1->h, BLACK);
6 rectfill(page2, 0, 0, page2->w, page2->h, BLACK);
7 
8 //Main Loop
9 while(!key[KEY_ESC])
10 {
11 mx = mouse_x;
12 my = mouse_y;
13 handleMouse();
14 if(game == 0)
15 {
16 if(checkTimer(100) > 0)
17 {
18 resetTimer();
19 if (activepage == page1)
20 activepage = page2;
21 else
22 activepage = page1;
23 }
24 detectSelection(mx, my);
25 show_video_bitmap(activepage);
26 }
27 }

I don't think theres anything wrong with my code, but I want to check.

miran
Member #2,407
June 2002

Which page do you draw to and where? You must draw to the page that is NOT being shown on screen at the time.

You should separate logic from drawing. Right now it seems you have it all mixed together.

This is how it hould be done:

while (!done) {
    while (timer_ticked) {
        process_input();
        process_logic();
    }

    draw_to_active_page();
    show_active_page();
    swap_pages();
}

--
sig used to be here

Brian Simpson
Member #6,645
December 2005
avatar

Ahh ok, I was doing it inproperly. (I had drawing code in the detectSelection and the handleMouse) I went ahead and fixed it up, and this is how it looks.

1void mainLoop()
2{
3 while(!key[KEY_ESC])
4 {
5 mx = mouse_x;
6 my = mouse_y;
7 if(game == 0)
8 {
9 if(checkTimer(100) > 0)
10 {
11 resetTimer();
12 handleMouse();
13 detectSelection(mx, my);
14 }
15 clearScreen();
16 updateMenu();
17 show_video_bitmap(activepage);
18 swapPages();
19 }
20 }
21}

I believe that's the correct way to do it, but I have two questions.

In handleMouse, I just pick out what action to do depending on what I have selected when I click on the left mouse button, is that considered logic?

And whenever I close the game and I'm selecting something, it occassionally crashes the game. I'm not sure why, but this is the code I have for when I close the game:

void endGame()
{
 destroy_bitmap(page1);
 destroy_bitmap(page2);
 destroy_bitmap(activepage);
 unload_datafile(media);
 allegro_exit();
}

It's called right after the mainLoop is called if you wanted to know. I don't think there is anything wrong with that, but obviously something is wrong. Oh, and thanks miran. :P

Christopher Bludau
Member #5,401
January 2005

are you drawing the mouse to any of those bitmaps you destroy?

destroying a bitmap to which the mouse is drawn will crash your game.

Brian Simpson
Member #6,645
December 2005
avatar

No, I only draw the mouse to the screen when the game is initalized.

EDIT: To test your theory, I ran scare_mouse(); when the game is ending and it fixed most the problem, but whenever I have my mouse in the lower parts of the screen when I close it, it closes fine, but it has a stupid error saying "Shimp Pong has encountered an error and needs to close". I don't think this is anything to worry about, but it's still annoying.

Evert
Member #794
November 2000
avatar

You must make sure that you call show_mouse(NULL) before destroying the surface the mouse is on.

Brian Simpson
Member #6,645
December 2005
avatar

Oh, well does scare_mouse() do the same thing? Or do I actually need to call show_mouse(NULL); ? And do I even need to destroy the activepage bitmap when I close the game? Shawn doesn't in his page flipping example.

Christopher Bludau
Member #5,401
January 2005

scare_mouse just tells allegro not to SHOW the mouse cursor.

but the mouse is still ASSIGNED to the selected bitmap.

with show_mouse(NULL) you deselect the mouse from any bitmap.

Maybe this is not 100% correct in technical terms, but that should explain what it does.

Evert
Member #794
November 2000
avatar

Quote:

Oh, well does scare_mouse() do the same thing?

Certainly not.

Quote:

scare_mouse just tells allegro not to SHOW the mouse cursor.

Not quite - it tells Allegro not to draw a soft mouse cursor. If the mouse cursor is drawn by teh OS, it does nothing.

Quote:

Or do I actually need to call show_mouse(NULL);

Depends: if the mouse is displayed to screen (which it normally is), then you only need to call show_mouse(NULL) if you explicitly call set_gfx_mode().

Quote:

And do I even need to destroy the activepage bitmap when I close the game?

Yes, you do. In practice, Allegro may free all video bitmaps when it closes down (memory bitmaps are immaterial, they are freed automatically by the OS), but you should always free memory that you allocate.

Quote:

Shawn doesn't in his page flipping example.

That's an oversight, then.

Brian Simpson
Member #6,645
December 2005
avatar

Ahh ok, thanks for clearing that up for me guys. It turns out that the scare_mouse(); wasn't doing the trick, so I changed it to show_mouse(NULL) and it did fixed it up good. Thanks a lot guys. If you don't mind I have one more question, and that's if I call

char *marquee;

as a global variable, do I need to call

free(marquee);

in the end game script?

BAF
Member #2,981
December 2002
avatar

Yeah, but you also have to malloc() or new it someplace too.

Brian Simpson
Member #6,645
December 2005
avatar

Oh ok, I "malloced" it before hand, I was just wondering if it was required since it was a global variable. Thanks a lot guys. ;D

Thomas Fjellstrom
Member #476
June 2000
avatar

 destroy_bitmap(page1);
 destroy_bitmap(page2);
 destroy_bitmap(activepage);

Slight problem there, you never actually created a third bitmap, activepage is just a "pointer" or alias for which ever of page1 or page2 is the activepage, so you really aught not to be calling destroy_bitmap on it, since the bitmap it was pointing to, has already been destroyed.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Brian Simpson
Member #6,645
December 2005
avatar

Well I still declared it as a global variable, but it's only a pointer so I don't need to destroy it after all?

Thomas Fjellstrom
Member #476
June 2000
avatar

Nope. Only call destroy_* on items that were specifically created with create_*. Otherwise you're freeing it twice, which is a rather bad thing.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

if the mouse is displayed to screen (which it normally is), then you only need to call show_mouse(NULL) if you explicitly call set_gfx_mode().

What? How does one implicitly call set_gfx_mode?

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

How does one implicitly call set_gfx_mode?

// set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
exit(0);

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Brian Simpson
Member #6,645
December 2005
avatar

Ok well I removed it and it works well, but shouldn't I set the activepage to NULL anyway when I close the game?

Thomas Fjellstrom
Member #476
June 2000
avatar

It is a good habit to get into.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Brian Simpson
Member #6,645
December 2005
avatar

Oh ok, I went ahead and did that. Thanks a lot guys. ;D

Go to: