Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Game Lag Windows to Linux - FPS issue?

This thread is locked; no one can reply to it. rss feed Print
Game Lag Windows to Linux - FPS issue?
AceBlkwell
Member #13,038
July 2011
avatar

All,

I've create a simple game that can use mouse or keyboard. When I compile with a Dell Latitude with Win 10, it functions fine. When I compile on Kubuntu 22.04 on Acer Nitro it lags. It starts out fair enough but the cursor I created starts leaving a trail. Also as I click the cards (match game) The first set does fine, the next a little slower and eventually you can't tell if it took your command it so slow. Again, this is only on the Linux compile.

I haven't set frames per second as I've seen on some of the tutorials. Is this the issue? Maybe the default FPS are different between the two machines? Thanks.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Edgar. I was surprised as you. I'm running Kubuntu in a dual boot. At first I thought it was a mingw32 (Windows) Vs a Linux GCC issue. Then I remembered that the tutorials I'd seen applied a frames per second command. I haven't had a chance to try it yet. I thought maybe by not defining FPS, the default difference between the two setups might be causing an issue.

In any case, here are the cards and drawing functions. There is a rest if the two cards / blocks don't match but thats not the lag. Lag come in after the cards flip back over to white and I click another block. A couple times of this and it's 1 to 3 secs waiting and I can't tell if my click was registered or not. Plus there is the cursor trailing. That's not critical. I can take it out and use the system cursor only. I just put it in to see if I could get it to work

#SelectExpand
1bool game_play(BLOCKS Blocks[]){ 2 3int iChoiceCount = 0; 4bool bQuit = false; 5int iFirstChoice = 0; 6int iSecondChoice = 0; 7int iKey = 0; 8int pos_x = 100; 9int pos_y = 100; 10 11while (!bQuit) 12{ 13 14 al_wait_for_event(queue, &event); 15 al_clear_to_color(COLOR::BLACK); 16 al_draw_textf(font, COLOR::BR_CYAN, 10, 20, 0, "Solly's Matches %i %i",pos_x,pos_y); 17 18 19 switch(iChoiceCount<2){ 20 case true: 21 draw_cards(Blocks,0.0,pos_x,pos_y); 22 break; 23 case false: 24 for(int count = 0;count<CQTY;count++){ 25 if(!Blocks[count].bMatched) 26 Blocks[count].bFlipped = false;} // Card Flip Cleared 27 iChoiceCount=0; 28 break; 29 } //end switch for iChoiceCount 30 31 32 if(event.type == ALLEGRO_EVENT_KEY_DOWN) 33 { 34 iKey = event.keyboard.keycode-1; 35 36 if(event.keyboard.keycode >= ALLEGRO_KEY_A && event.keyboard.keycode <= ALLEGRO_KEY_X ){ 37 Blocks[iKey].bFlipped = true; 38 if(iChoiceCount == 0) iFirstChoice = iKey; 39 if(iChoiceCount == 1) iSecondChoice = iKey; 40 iChoiceCount++; 41 } // end if for block choice 42 else if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 43 bQuit = true; 44 if(iChoiceCount == 2){ 45 if(Blocks[iFirstChoice].iValue == Blocks[iSecondChoice].iValue ){ 46 Blocks[iFirstChoice].bMatched = true; 47 Blocks[iSecondChoice].bMatched = true; }} 48 49 if((Blocks[iFirstChoice].bFlipped && Blocks[iSecondChoice].bFlipped )&&(Blocks[iFirstChoice].iValue != Blocks[iSecondChoice].iValue )){ 50 draw_cards(Blocks,2.0,pos_x,pos_y); 51 } 52 }// end if event.type 53 54 else if(event.type == ALLEGRO_EVENT_MOUSE_AXES) 55 { pos_y = event.mouse.y; 56 pos_x = event.mouse.x; 57 } // end mouse axis 58 59 else if(event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN){ 60 for(int count = 0;count<CQTY;count++){ 61 if(pos_x >= Blocks[count].fTX && pos_y >= Blocks[count].fTY){ 62 if(pos_x <= Blocks[count].fBX && pos_y <= Blocks[count].fBY){ 63 Blocks[count].bFlipped = true; 64 if(iChoiceCount == 0) iFirstChoice = count; 65 if(iChoiceCount == 1) iSecondChoice = count; 66 iChoiceCount++; 67 }}}// end for 68 if(iChoiceCount == 2){ 69 if(Blocks[iFirstChoice].iValue == Blocks[iSecondChoice].iValue ){ 70 Blocks[iFirstChoice].bMatched = true; 71 Blocks[iSecondChoice].bMatched = true; }} 72 73 if((Blocks[iFirstChoice].bFlipped && Blocks[iSecondChoice].bFlipped )&&(Blocks[iFirstChoice].iValue != Blocks[iSecondChoice].iValue )){ 74 draw_cards(Blocks,2.0,pos_x,pos_y); 75 } 76 }// end button down 77 78 else if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 79 bQuit = true; 80 81 draw_cards(Blocks,0.0, pos_x,pos_y); 82}// end while() 83 84 return true; 85 86} //end game_play() 87 88void draw_cards(BLOCKS Blocks[],float fStall,int pos_x, int pos_y){ 89 for(int count = 0;count<CQTY;count++){ 90 if(!Blocks[count].bFlipped){ 91 al_draw_filled_rectangle(Blocks[count].fTX, Blocks[count].fTY, Blocks[count].fBX, Blocks[count].fBY, Blocks[count].aBackColor); 92 al_draw_textf(font, COLOR::BLACK, Blocks[count].fCX,Blocks[count].fCY, ALLEGRO_ALIGN_CENTRE, "%c",'A'+count);}//end if flipped 93 else 94 al_draw_filled_rectangle(Blocks[count].fTX, Blocks[count].fTY, Blocks[count].fBX, Blocks[count].fBY, Blocks[count].aFrontColor); 95 } 96 al_draw_filled_rectangle(pos_x, pos_y, pos_x+10,pos_y+10, COLOR::YELLOW); 97 al_flip_display(); 98 al_rest(fStall); 99} // end draw_cards()

It might help to have the structure code.

#SelectExpand
1/********************************** 2** matches.h * 04/25/23** 3** ************ 4** Matches game data ** 5***********************************/ 6 7#ifndef MATCHES_H_ 8#define MATCHES_H_ 9 10#define STX 25 11#define STY 75 12#define CQTY 24 13 14struct BLOCKS { 15 float fTX; 16 float fTY; 17 float fBX; 18 float fBY; 19 bool bMatched; 20 bool bFlipped; 21 int iValue; 22 float fCX; 23 float fCY; 24 ALLEGRO_COLOR aFrontColor; 25 ALLEGRO_COLOR aBackColor; 26}; 27 28#endif /* MATCHES_H_ */

DanielH
Member #934
January 2001
avatar

don't know if this will help or not but

Take the al_flip_display out of the draw_cards and put in main loop. You call draw_cards twice during one loop.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Daniel, I'll give it a shot. I'll let you know what happens.

DanielH
Member #934
January 2001
avatar

Actually I see 5 times you have draw_cards. five times the display gets flipped. But you only clear the screen at the beginning.

Might but hello with lag, but your trailing graphics.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Daniel. Times like these I miss the old days of MS Quick C. It had a step function that treated your code like a BASIC line interpreter. You could execute your code line at a time. It allowed you to watch the values of listed variables as well as seeing if your code made it in to loops or functions as expected. Was a big help in trouble shooting. Now I have to pepper in print statements to monitor variable and position in the code. But I digress. Thanks again.

Dizzy Egg
Member #10,824
March 2009
avatar

You can always put in some breakpoints and step through the code checking variables and each step as you go!!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

You've really got to format your code better with proper indentation and a single brace style. It makes it hard to read.

Also, your event loop needs a little work. Wait for an event as long as the queue is not empty (it will be an instant wait). Draw once. Do logic once for each tick of the system timer.

Finally, learn to use gdb, the gnu debugger. It will let you step through code and print out values of variables. Check out my debugging guide on the wiki here :

https://github.com/liballeg/allegro_wiki/wiki/Debugging-and-logging-with-A5#debugging-with-gdb

8-)

AceBlkwell
Member #13,038
July 2011
avatar

Thanks for the recommendation Dizzy and Edgar. I'll check them out. Being able to step through would be a big help.

As for code, I agree it's a little sketchy. First off, I wasn't planning on sharing ;D. My original question was about the possible impact of not using FPS. I usually do a better job of cleaning up once the program is going into final phase. As for this code, I've patch worked it together. Recently I moved it into the game_play function. It was all in one function (main). I've been adding aspects (letter location, mouse use) as I went just to see if I could do it.

Plus I'm primarily self taught, I'm sure I've developed poor habits. I need to read other's code for template ideas.

Thanks All.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

No time to learn like the present. That GDB guide has most all the commands I use anyway.

Look up style guides for tips on formatting your code. I use something like this :

int main(int argc , char** argv) {// braces go on the end of the line
   // 3 space indent for new block, eliminates the need for braces (in Python)
   if (condition1) {
      dothis();
   else if (condition2) {/// all ifs and elses in the same clause go at the same indentation
      dothat();
   } else {
      stop();
   }
}// closing brace goes on the same indentation level with the line of the starting brace

This is typical C++ style. C users probably want the opening brace on its own line.

As for an event loop, you need to exhaust all events. You were drawing something like 5 times per event, which would make it horribly slow and back up the event queue.

This is a typical event loop for me :

#SelectExpand
1bool quit = false; 2bool redraw = true; 3while (!quit) { 4 if (redraw) { 5 Draw(); 6 redraw = false; 7 } 8 do { 9 ALLEGRO_EVENT ev; 10 al_wait_for_event(queue , &ev); 11 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {quit = true;} 12 else if (ev.type == ALLEGRO_EVENT_TIMER) { 13 Logic(); 14 redraw = true; 15 } 16 } while (!al_is_event_queue_empty(queue)); 17}

DanielH
Member #934
January 2001
avatar

Don't listen to these heathens!

Open curly brace on new line!! ;D;D

There are arguments both ways. There is no 'correct' way to do it.

But yes, break those coding habits early. Proper indentation. Separate input from logic from drawing.

1. process input (events)
2. run logic based on that input
3. draw

You can draw every time pass through the loop or draw only when something happened. That is why Edgar had a redraw boolean. It only triggered a redraw because logic processing occurred.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

DanielH
Member #934
January 2001
avatar

It's as bad as people who pronounce gif as gift without the 't' instead of jif!

Dizzy Egg
Member #10,824
March 2009
avatar

I use same line opening brace in Java and new line opening brace in C/C++, mainly because my enforced gradle tasks demand I do!

Just to add to the debate 😎

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Polybios
Member #12,293
October 2010

Edgar said:

   if (condition1) {
      dothis();
   else if (condition2) {/// all ifs and elses in the same clause go at the same indentation
      dothat();
   }

Close your braces. >:(

AceBlkwell
Member #13,038
July 2011
avatar

Ok to carry it further. In Edgar's example that Polybios referred to, should we use braces for ease of reading when they aren't needed?

With a single statement after the if condition, couldn't you do this?

if (condition1)
dothis();
else if (condition2)
dothat();

I can't get the proper formatting. I have the dothis and do that indented.

Dizzy Egg
Member #10,824
March 2009
avatar

In my opinion, using brackets is always preferred, it just makes it easier to read and means you'll make less mistakes when coming back to add code etc.

When you say you couldn't get proper formatting, did you mean on here? Just wrap it in code tags to get formatting. Ie, I would do:

if (condition1)
{
    dothis();
}
else if (condition2)
{
    dothat();
}

It will also mean anyone else looking at your code will have an easier time!!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

AceBlkwell
Member #13,038
July 2011
avatar

Ok Dizzy, which formatting are you referring to? If I just add spaces the site ignores them, If I do the code format it put the code in a separate box. Thanks.

Dizzy Egg
Member #10,824
March 2009
avatar

Hmm, yeah just code tags....I'm not sure why it sometimes puts it in a box!? Maybe over a certain number of lines? Let me test it!

#SelectExpand
1if (true) 2{ 3} 4if (true) 5{ 6} 7if (true) 8{ 9} 10if (true) 11{ 12} 13if (true) 14{ 15} 16if (true) 17{ 18} 19if (true) 20{ 21}

if (true)
{
}

Yeah I think it's just if you have too many lines it puts it in a box!!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

Thanks Edgar, I've use the Formatting help box several times. I thought it put everything in a code box not just format it.

So Dizzy your saying

#SelectExpand
1if(COL > LIMIT) 2 codebox(); 3else 4 textbox();

See no matter how few lines I get the box.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

Oh that’s odd! I only seem to get a box of add lots of lines! Maybe a newline/carriage return OS thingy…

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

AceBlkwell
Member #13,038
July 2011
avatar

I agree Edgar. I was minimizing to see if I got the correct formatting.

I also agree the braces are clearer. I've had a few times where the indention gets messed up in copy/paste and shifting code around. With a single line if/else, followed by a mis-indented line, it's easy to forget what goes with what.

#SelectExpand
1 2if(this == that) 3{ 4 BunchOfStuff(Do); 5} 6else 7 DoNothing(); 8 WhoAmI(else || NDependent); // easy to forget this isn't associated with the else

Go to: