Here is an abbreviated version of events, excuse the pun...
i have added extra descriptive comments to try and make easy reading.
the function TestMove() only checks the surrounding area and does no action on the current 'peg'
Code:
void PlayState::Do_Logic()
{
static int oldX, oldY;
bool valid_move = false;
bool record_move = false;
//if statement to test (mouseX && mouseY are within the bounds of the item)
//then .....
switch(event.type)
{
case SDL_MOUSEBUTTONUP:
{
if(!active_move) //if no peg currently selected.
{
if(pegArray[dwn][acr] == PEG) //only if the item clicked on is a peg
{
pegArray[dwn][acr] = SELEC; //mark the peg as selected
peg_chosen = true;
active_move = true;
oldY = dwn; //record the position of the selected peg;
oldX = acr; //
pegclip[dwn][acr].x = PGREEN; //Show as selected with the green select mask
}
else
pegclip[dwn][acr].x = PH_MASK; //if not a peg item can only be a peghole, set mask
}
else
{
if(active_move) //if a peg has already been selected
{
if(pegArray[dwn][acr] == PEGHL) //only if this ButtonUP is over a destination peghole
{
valid_move = TestMove(oldX, oldY);
if(valid_move)
{
pegArray[oldY][oldX] = PEGHL; //Set the old selected peg status to Peghole
pegclip[oldY][oldX].x = PH_MASK; //set its mask to peghole
pegArray[dwn][acr] = PEG; //set destination peghole to status Peg
pegclip[dwn][acr].x = PG_MASK; //set its mask to normal peg
oldY = 0; //reset these ready for next move
oldX = 0; //
peg_chosen = false; //
active_move = false; //
valid_move = false; //
record_move = true; //indicate that a new move should be stored in the undo buffer
}
else pegclip[dwn][acr].x = PH_NON; //if non-legal destination show invalid peghole mask
}
else
pegclip[dwn][acr].x = PG_MASK; //if not the item can only be a peg, set mask
if(pegArray[dwn][acr] == SELEC) //if ButtonUP was on the already selected peg do deselect operations.
{
pegArray[dwn][acr] = PEG; //set it back to a normal unselected peg
peg_chosen = false; //reset these ready for next move
active_move = false; //
pegclip[dwn][acr].x = PG_MASK; //show as deselected with default peg mask,
}
}
}
break;
}
}
}
the relevant loop in main() is simply >
Code:
while(stateID != EXITSTATE)
{
currentstate->HandleEvents();
currentstate->Do_Logic();
ChangeState();
currentstate->Render();
SDL_UpdateRect(screen, 0, 0,0,0);
}
HandleEvents() only checks for exit requests and gets the x & y coords of the mouse and global event.type to use in logic
Do_Logic() relevant part is as above
nothing relevant happens in changestate() when testing this bug as no change event occurs.
Render() is just a straightforward loop to Blit clips.
When the program is slowed down after a buttonup event over a peg you can see the mask applied alternate with each loop, the first one is as it should be, the green Selected mask, then it goes back to a default (as though deselected) then it is green again like selected, etc etc.
If no mouse event occurs after the ButtonUP even,t stepping through shows the mouse x+y are of course retained the same, so on the next gameloop they pass into the IF condition shown,
but then (when stepping through at least) there is as stated, no new event and the switch block is skipped, so nothing should change.
However, when left to run as normal, the program is somehow getting into the 'if(already an activemove)' block on the very next loop,
but this should only occur after the next Buttonup event, this is how the mask is getting set back to default as i think it meets the if(the peg already selected) condition and is treated as a deselect request.
more strangely it somehow manages to get back into the selected status on the next loop and thus apply the Green mask again, etc ad nauseum.
and as i said another version of this same loop works ok, its just that it is not in a state manager design.
I appreciate any help from anyone that has the time or inclination to trawl through this ramble!
EDIT :
have written out to a file using get mouse state and see that the mouse button is continually showuing as pressed/button event in this bug,
i need to stop that in SDL.