Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Mouse Lag / Not Keyboard

This thread is locked; no one can reply to it. rss feed Print
Mouse Lag / Not Keyboard
AceBlkwell
Member #13,038
July 2011
avatar

Following up on my Linux Vs Windows FPS question. A quick recap, when I compile my match game in Windows 10, the game functions pretty good considering where I'm at in the fine tuning. However when I compile in Linux Kubuntu 22, the game works the same initially but quickly starts lagging. After about 3-4 attempts to match colors (concentration type game for grandkids) it lags to the point you can't tell if it's read your response or not.

Well this weekend I was showing someone the program and got the same lag until I used the keyboard instead of mouse to flip the cards. The game allows for both. So my question, would there be a difference in mouse reaction OS to OS? It doesn't appear to be so with the keyboard. Thanks

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

DanielH
Member #934
January 2001
avatar

Is the same code as before or have you fixed that? There has got to be something else.

As always, code please.

AceBlkwell
Member #13,038
July 2011
avatar

Thanks guys, I'll clean my code up and post it.

UPDATE: Until then, The need for seeing the code would imply that code flow can affect variation in performance machine to machine. Is this the case? Meaning if the code is lacking (and I'm sure it is in some areas) wouldn't it be the same lacking code on both Windows and Linux? I would think the issue would lie in the OS or the machine itself. Just thinking out loud.

DanielH
Member #934
January 2001
avatar

No code means we are guessing what the problem could be instead of giving clear answers.

AceBlkwell
Member #13,038
July 2011
avatar

Ok all. Here is the code that involves drawing to screen.

Main with title screen

#SelectExpand
1/**********************INCLUDES ***********************/ 2#include <cstdio> 3#include <cstdlib> 4#include <iostream> 5#include <string> 6#include <allegro5/allegro5.h> 7#include <allegro5/allegro_font.h> 8#include <allegro5/allegro_ttf.h> 9#include <allegro5/allegro_image.h> 10#include <allegro5/allegro_primitives.h> 11#include <allcolor_A5.h> 12#include <matches.h> 13 14/********************* DEFINES *******/ 15 16/********************* STRUCTS *******/ 17 18/********************* FUNCTION DECLARE ******/ 19void a_init(); 20bool game_play(BLOCKS[]); 21void card_setup(BLOCKS[]); 22void match_setup(BLOCKS[]); 23 24/********************* EXTERNALS ******/ 25extern ALLEGRO_TIMER* timer; 26extern ALLEGRO_EVENT_QUEUE* queue; 27extern ALLEGRO_DISPLAY* disp; 28extern ALLEGRO_FONT* font; 29extern ALLEGRO_FONT* scr_font; 30extern ALLEGRO_EVENT event; 31extern ALLEGRO_BITMAP* titlescr; 32/******************* Main() *****************/ 33int main(int argc, char *argv[]) 34{ 35bool bQuit = false; 36BLOCKS Blocks[CQTY]; 37int pos_x = 100; 38int pos_y = 100; 39 40 a_init(); 41 card_setup(Blocks); 42 match_setup(Blocks); 43 44 45 46while (!bQuit) 47{ 48 49 al_wait_for_event(queue, &event); 50 al_clear_to_color(COLOR::BLACK); 51 52 53 al_draw_bitmap(titlescr, 0,0, 0); 54 al_flip_display(); 55 if(event.type == ALLEGRO_EVENT_KEY_DOWN) 56 { 57 if(event.keyboard.keycode == ALLEGRO_KEY_P) 58 bQuit = game_play(Blocks); 59 else if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE ||event.keyboard.keycode == ALLEGRO_KEY_P) 60 bQuit = true; 61 }// end if event.type 62 63 else if(event.type == ALLEGRO_EVENT_MOUSE_AXES) 64 { pos_y = event.mouse.y; 65 pos_x = event.mouse.x; 66 } // end mouse axis 67 68 else if(event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 69 { 70 if(pos_x >= 489 && pos_y >= 343) 71 { 72 if(pos_x <= 575 && pos_y<= 379) 73 { 74 bQuit = game_play(Blocks); 75 } 76 }// end location if 77 if (pos_x >= 489 && pos_y >= 415) 78 { 79 if(pos_x <= 575 && pos_y<= 451) 80 { 81 bQuit = true; 82 } 83 }// end location if 84 }// end button down 85 86 else if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 87 bQuit = true; 88 89}// Screen While 90 91al_destroy_display(disp); 92al_destroy_event_queue(queue); 93 94} //end main()

This is the game play function with the draw function.

#SelectExpand
1/**********************INCLUDES ***********************/ 2#include <iostream> 3#include <string> 4#include <allegro5/allegro5.h> 5#include <allegro5/allegro_ttf.h> 6#include <allegro5/allegro_font.h> 7#include <allegro5/allegro_primitives.h> 8#include <allegro5/matches.h> 9#include <allcolor_A5.h> 10#include <matches.h> 11 12/********************* FUNCTION DECLARE ******/ 13int random_no(int); 14void draw_cards(BLOCKS[], float,int, int); 15 16/********************* EXTERNALS ******/ 17extern ALLEGRO_TIMER* timer; 18extern ALLEGRO_EVENT_QUEUE* queue; 19extern ALLEGRO_DISPLAY* disp; 20extern ALLEGRO_FONT* font; 21extern ALLEGRO_FONT* scr_font; 22extern ALLEGRO_EVENT event; 23 24/******************* game_play() *****************/ 25 26bool game_play(BLOCKS Blocks[]) 27{ 28 29int iChoiceCount = 0; 30bool bQuit = false; 31int iFirstChoice = 0; 32int iSecondChoice = 0; 33int iKey = 0; 34int pos_x = 100; 35int pos_y = 100; 36int iPlayer[2] = {0,0}; 37int iTurn = 0; 38int iTurnPos = 0; 39bool bTurn = false; 40 41while (!bQuit) 42{ 43 44 al_wait_for_event(queue, &event); 45 al_clear_to_color(COLOR::BLACK); 46 al_draw_textf(font, COLOR::BR_CYAN, 150, 20, 0, "PICK A BLOCK"); 47 al_draw_textf(font, COLOR::BR_RED, 10, 450, 0, "Solly's Matches %i",iPlayer[0]); 48 al_draw_textf(font, COLOR::BR_GREEN, 35, 480, 0, "Luna's Matches %i",iPlayer[1]); 49 50 if(iTurn == 0) 51 iTurnPos = 450; 52 if(iTurn == 1) 53 iTurnPos = 480; 54 al_draw_textf(font, COLOR::BR_MAGENTA, 450, iTurnPos, 0, "<---"); 55 56 57 switch(iChoiceCount<2) 58 { 59 case true: 60 draw_cards(Blocks,0.0,pos_x,pos_y); 61 break; 62 case false: 63 for(int count = 0;count<CQTY;count++) 64 { 65 if(!Blocks[count].bMatched) 66 { 67 Blocks[count].bFlipped = false; 68 } 69 } // Card Flip Cleared 70 iChoiceCount=0; 71 break; 72 } //end switch for iChoiceCount 73 74 75 if(event.type == ALLEGRO_EVENT_KEY_DOWN) 76 { 77 iKey = event.keyboard.keycode-1; 78 79 if(event.keyboard.keycode >= ALLEGRO_KEY_A && event.keyboard.keycode <= ALLEGRO_KEY_X ) 80 { 81 Blocks[iKey].bFlipped = true; 82 if(iChoiceCount == 0) iFirstChoice = iKey; 83 if(iChoiceCount == 1) iSecondChoice = iKey; 84 iChoiceCount++; 85 } // end if for block choice 86 else if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 87 bQuit = true; 88 89 if(iChoiceCount == 2) 90 { 91 if(Blocks[iFirstChoice].iValue == Blocks[iSecondChoice].iValue ) 92 { 93 Blocks[iFirstChoice].bMatched = true; 94 Blocks[iSecondChoice].bMatched = true; 95 iPlayer[iTurn]++; 96 bTurn = true; 97 } // end match if 98 99 switch(iTurn) 100 { 101 case 0: 102 if(!bTurn) 103 iTurn = 1; 104 bTurn = false; 105 break; 106 case 1: 107 if(!bTurn) 108 iTurn = 0; 109 bTurn = false; 110 break; 111 } // end iTurn switch 112 }// end if iChoiceCount == 2 actions 113 114 if((Blocks[iFirstChoice].bFlipped && Blocks[iSecondChoice].bFlipped )&&(Blocks[iFirstChoice].iValue != Blocks[iSecondChoice].iValue )) 115 { 116 draw_cards(Blocks,2.0,pos_x,pos_y); 117 } 118 }// end if event.type 119 120 else if(event.type == ALLEGRO_EVENT_MOUSE_AXES) 121 { pos_y = event.mouse.y; 122 pos_x = event.mouse.x; 123 } // end mouse axis 124 125 else if(event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 126 { 127 for(int count = 0;count<CQTY;count++) 128 { 129 if(pos_x >= Blocks[count].fTX && pos_y >= Blocks[count].fTY) 130 { 131 if(pos_x <= Blocks[count].fBX && pos_y <= Blocks[count].fBY) 132 { 133 Blocks[count].bFlipped = true; 134 if(iChoiceCount == 0) iFirstChoice = count; 135 if(iChoiceCount == 1) iSecondChoice = count; 136 iChoiceCount++; 137 } 138 } 139 }// end for 140 if(iChoiceCount == 2) 141 { 142 if(Blocks[iFirstChoice].iValue == Blocks[iSecondChoice].iValue ) 143 { 144 Blocks[iFirstChoice].bMatched = true; 145 Blocks[iSecondChoice].bMatched = true; 146 iPlayer[iTurn]++; 147 bTurn = true; 148 } // end match if 149 150 switch(iTurn) 151 { 152 case 0: 153 if(!bTurn) 154 iTurn = 1; 155 bTurn = false; 156 break; 157 case 1: 158 if(!bTurn) 159 iTurn = 0; 160 bTurn = false; 161 break; 162 } // end iTurn switch 163 }// end if iChoiceCount == 2 actions 164 165 if((Blocks[iFirstChoice].bFlipped && Blocks[iSecondChoice].bFlipped )&&(Blocks[iFirstChoice].iValue != Blocks[iSecondChoice].iValue )) 166 { 167 draw_cards(Blocks,2.0,pos_x,pos_y); 168 } 169 }// end button down 170 171 else if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 172 bQuit = true; 173 174 draw_cards(Blocks,0.0, pos_x,pos_y); 175}// end while() 176 177return true; 178 179} //end game_play() 180 181void draw_cards(BLOCKS Blocks[],float fStall,int pos_x, int pos_y) 182{ 183 for(int count = 0;count<CQTY;count++) 184 { 185 if(!Blocks[count].bFlipped) 186 { 187 al_draw_filled_rectangle(Blocks[count].fTX, Blocks[count].fTY, Blocks[count].fBX, Blocks[count].fBY, Blocks[count].aBackColor); 188 al_draw_textf(font, COLOR::BLACK, Blocks[count].fCX,Blocks[count].fCY, ALLEGRO_ALIGN_CENTRE, "%c",'A'+count); 189 }//end if flipped 190 else 191 al_draw_filled_rectangle(Blocks[count].fTX, Blocks[count].fTY, Blocks[count].fBX, Blocks[count].fBY, Blocks[count].aFrontColor); 192 } 193 194 al_flip_display(); 195 al_rest(fStall); 196} // end draw_cards()

BTW, the format doesn't keep the spacing accurately.

Dizzy Egg
Member #10,824
March 2009
avatar

It looks like you’re still calling draw_blocks multiple times in the loop. You should only draw once per loop. As you are flipping the display and also using al_rest it will have adverts effects. It may not be as noticeable on windows because of the dwmflush calls/vsync etc. you should update the logic and draw/delay once per loop.

Ideally you would use a timer and only draw when the timer clicks.

----------------------------------------------------
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 for the expertise guys,

Looking over the code, I see a circumstance where I draw twice in one loop. I have specific conditions for each of the draw calls. They shouldn’t all draw in a single loop. I’ll have to read closer to see if there is a circumstance where multiple draws are active in a single loop. Currently I have different conditions to be met for each draw. Then I have a default should none of the previous condition be met. I see where the default gets drawn each time through the loop regardless of the other conditions. I need to condition it in some way too I supposed.

Here is why I put the different draw calls. Originally I didn’t have this. As a person chooses the first card, it stays flipped because of a bool variable change. However, when the second card / block is chosen that doesn’t match, all the flip variables are zeroed out. This happens so fast that you don’t get to see your second card. I had to add a rest of 2.0 sec but only when two cards have been chosen and don’t match.

In any case, I’ll rethink the code flow and try to work off of a timer. Thanks again.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

AceBlkwell
Member #13,038
July 2011
avatar

I agree Edgar. I'll look into a timer. Obviously you guys know a lot more about it than I do. I'll keep you posted. I've also being thinking of how to reduce the draw call to a single call from the timer event. Instead of various locations. That may help as well. Thanks.

DanielH
Member #934
January 2001
avatar

Simple loop system with input handling, logic processing and output.

draw_cards would go in the draw loop ONCE. If you need a delay timer to show the face before turning over, then add another variable just for that. Set it to some arbitrary time that counts down every logic tick. When zero flip the cards back over.

#SelectExpand
1bool shutdown = false; 2bool dirty = true; 3int32_t counter = 0; 4 5int32_t loop() 6{ 7 while (!shutdown) 8 { 9 input(); 10 11 while (counter > 0) 12 { 13 logic(); 14 --counter; 15 } 16 17 if (dirty) 18 { 19 draw(); 20 dirty = false; 21 } 22 23 al_rest(0.01); 24 } 25 26 return 0; 27} 28 29void draw() 30{ 31 al_clear_to_color(al_map_rgb(64, 0, 64)); 32 33 al_flip_display(); 34} 35 36// process current input status 37void logic() 38{ 39 40 dirty = true; 41} 42 43void input() 44{ 45 ALLEGRO_EVENT event; 46 47 while (!al_event_queue_is_empty(queue)) 48 { 49 al_get_next_event(queue, &event); 50 51 switch (event.type) 52 { 53 case ALLEGRO_EVENT_TIMER: 54 { 55 ++counter; 56 } break; 57 58 case ALLEGRO_EVENT_DISPLAY_CLOSE: 59 { 60 shutdown = true; 61 } break; 62 } 63 } 64}

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Go to: