Console game problems - PLEASE URGENT

I'm building a console game, but i'm having problems with the mouse code. I need to check if a certain coordenate has been clicked on. I tried using a bool, but it doesn't work... Any ideas?


#define _WIN32_WINNT 0x0500

#include <cstdlib>
#include <iostream>
#include <process.h>
#include <windows.h>
#include <time.h>
#include <stdio.h>

using namespace std;


class MouseInputHandler
{
//mouse input handler callback function pointer
typedef void(*MIHCB)(int, int, void*);

public:
MouseInputHandler(){}
~MouseInputHandler(){}
void init();

inline void start_polling()
{
_beginthread(polling_function, 0, this);
polling = true;
}

inline void stop_polling()
{
input.quit = true;
while (polling);
}

int getx();
int gety();
void getxy(int & x, int & y);

//setting the callbacks
inline void set_lbdcb(MIHCB f){ lbdcb = f; }
inline void set_lbucb(MIHCB f){ lbucb = f; }
inline void set_lbccb(MIHCB f){ lbccb = f; }

//setting the params for the callbacks
inline void set_lbdcbp(void*p){ lbdcbp = p; }
inline void set_lbucbp(void*p){ lbucbp = p; }
inline void set_lbccbp(void*p){ lbccbp = p; }

private:
struct MouseInput
{
//current and previous mouse button status
int cleft, pleft;

bool quit;
int x, y;

} input;

bool polling;

static void polling_function(void*);
static inline int is_pressed(int key)
{
return (GetAsyncKeyState(key) >> 15);
}

MIHCB lbdcb;
MIHCB lbucb;
MIHCB lbccb;

void* lbdcbp;
void* lbucbp;
void* lbccbp;

};

void MouseInputHandler::polling_function(void*p)
{
MouseInputHandler * m = (MouseInputHandler*)p;

m->input.quit = false;

HWND window = GetConsoleWindow();
RECT wpos;
POINT cpos;


m->input.cleft = m->input.pleft = false;
int x, y;
int tl, t;


while (!m->input.quit)
{
GetWindowRect(window, &wpos);
GetCursorPos(&cpos);

cpos.x -= wpos.left;
cpos.y -= wpos.top;

//transform screen to console coords
x = (cpos.x - 5) / 8;
y = (cpos.y - 25) / 12;

m->input.cleft = is_pressed(VK_LBUTTON);

//mouse down event: it was up and now is down
if (m->input.cleft && !m->input.pleft)
{
tl = (clock() * 1000) / CLOCKS_PER_SEC;
m->lbdcb(x, y, m->lbdcbp);
}

//mouse up event: it was down and now is up
if (!m->input.cleft && m->input.pleft)
{
t = (clock() * 1000) / CLOCKS_PER_SEC;
m->lbucb(x, y, m->lbucbp);

//mouse click event:
//down->up in less than 100 ms
if (t - tl <= 100)
m->lbccb(x, y, m->lbccbp);
}

//...more stuff here

m->input.pleft = m->input.cleft;

Sleep(25);
}
m->polling = false;
}

////////////////////////////////////////////////////////////////////////////////

void left_down(int x, int y, void*p)
{
printf("left button down at (%d,%d)\n", x, y);
}

void left_up(int x, int y, void*p)
{
printf("left button up at (%d,%d)\n", x, y);
}

void left_click(int x, int y, void*p)
{
printf("left click at (%d,%d)\n", x, y);
}

bool left_click1(int x, int y){
if (x==y) return true;
else return false;

}
int main()
{
cout << "Moves: " << "\t" << "Last Move: " " " << endl;
int m_nSize=7;
{
for (int xtab = 0; xtab < m_nSize / 4; xtab++) cout << "\t ";
cout << "Light Up! " << endl;
// Draw the squares
cout << " ";
for (int col = 0; col < m_nSize; col++){ printf(" %2d", col); }
printf("\n");

for (int row = 0; row < 2 * m_nSize; row++){
if (row == 0)//PRIMEIRA LINHA
{
cout << " " << (char)218;
for (int col = 0; col < m_nSize - 1; col++){ cout << (char)196 << (char)196 << (char)196 << (char)194; }

cout << (char)196 << (char)196 << (char)196 << (char)191 << endl;
}
if (row == 2 * m_nSize - 1)//ULTIMA LINHA
{
cout << " " << (char)192;
for (int col = 0; col < m_nSize - 1; col++){ cout << (char)196 << (char)196 << (char)196 << (char)193; }
cout << (char)196 << (char)196 << (char)196 << (char)217 << endl;
}
else{

if (row % 2 == 0){
printf("%2d %c", row / 2, 179);
}
else{
cout << " ";
for (int col = 0; col < m_nSize; col++){
if (col == 0) cout << (char)195;
cout << (char)196 << (char)196 << (char)196;
if (col == m_nSize - 1) cout << (char)180;
else cout << (char)197;
}
}
cout << endl;

}
}
}


MouseInputHandler mouse;
mouse.set_lbdcb(left_down);
mouse.set_lbucb(left_up);
mouse.set_lbccb(left_click);

cout << "hit esc anytime to quit" << endl;

mouse.start_polling();

while (!(GetAsyncKeyState(VK_ESCAPE) >> 15));

if (left_click1) cout << "clicked"<< endl;

mouse.stop_polling();

system("pause");
return 0;
}
Last edited on
I skimmed... and stopped once I saw you were using threads to get mouse input.

Creating a separate thread to poll for mouse input is a little crazy. Not only that... but multithreading is one of the most complex topics in C++. I'm willing to wager you are seeing problems because you are not guarding any variable accesses (ie: you have tons of race conditions).

My advice:

- Don't use the console for this. Hacking up the console to do this kind of thing is a lot more work than just using a normal graphical window. Look into libs like SFML or SDL ... it's really super easy. Not only are those libs easier than what you're doing... but they also are portable... and you'll be able to use actual graphics instead of a stupid console window.

- Don't use additional threads unless you have a very compelling reason to. Adding new threads opens up a big can of worms that cause a lot of problems and require careful consideration. Unless there are significant upsides to adding additional threads -- you probably shouldn't be doing it.

- If you insist on using the console... and insist on using threads... then read up on mutexes. The idea behind a mutex is that you lock and unlock it. When you lock it... it guarantees that no other threads will have the same mutex locked (ie: only 1 thread can have it locked at a time). This will allow you to read/write variables that are shared between multiple threads. Failure to do this will result in one thread reading a var while another thread attempts to write it -- when both happen at the same time, you get a "race condition" that causes extremely screwy behavior. It's very bad.

- Any and all variables that are used by more than 1 thread must be guarded to protect against race conditions. There are no exceptions. Either you need to make sure all accesses are behind mutexes... or you need to make the variables atomic (see C++11's <atomic> header).


But again... multithreading is complex and difficult. I strongly recommend against it... especially for such an otherwise simple program.


EDIT: I also fail to see what's "URGENT" about this.
Last edited on
Topic archived. No new replies allowed.