From 47dcce1ed989159bbe0fc2a98ebeda4f5dc99772 Mon Sep 17 00:00:00 2001 From: Wilrik de Loose Date: Tue, 27 May 2008 14:20:29 +0000 Subject: menu + button afhandeling --- matchblox/common/textfile.cpp | 2 +- matchblox/engine/C_MatchBloxEngine.cpp | 49 +- matchblox/engine/C_MatchBloxEngine.h | 2 +- matchblox/lib/WiiYourself!.lib | Bin 328086 -> 25718 bytes matchblox/main.cpp | 9 +- matchblox/matchblox.vcproj | 6 +- matchblox/menu/button.c | 27 +- matchblox/menu/button.h | 28 +- matchblox/menu/menu.c | 834 +++++++++++++++++---------------- matchblox/menu/menu.h | 3 +- matchblox/menu/menu_msg.c | 63 +++ matchblox/menu/menu_msg.h | 23 + 12 files changed, 613 insertions(+), 433 deletions(-) create mode 100644 matchblox/menu/menu_msg.c create mode 100644 matchblox/menu/menu_msg.h diff --git a/matchblox/common/textfile.cpp b/matchblox/common/textfile.cpp index 0b74282..db3a2f1 100644 --- a/matchblox/common/textfile.cpp +++ b/matchblox/common/textfile.cpp @@ -34,7 +34,7 @@ char *textFileRead(char *fn) { if (count > 0) { content = (char *)malloc(sizeof(char) * (count+1)); - count = fread(content,sizeof(char),count,fp); + count = fread(content,sizeof(char),(size_t)count,fp); content[count] = '\0'; } fclose(fp); diff --git a/matchblox/engine/C_MatchBloxEngine.cpp b/matchblox/engine/C_MatchBloxEngine.cpp index a78e649..6984239 100644 --- a/matchblox/engine/C_MatchBloxEngine.cpp +++ b/matchblox/engine/C_MatchBloxEngine.cpp @@ -16,6 +16,7 @@ #include "bitmap.h" #include "message_queue.h" #include "message_input.h" +#include "menu_msg.h" #include "wiimote_utils.h" #include "C_Smoother.h" #include "C_MatchBloxEngine.h" @@ -87,23 +88,49 @@ GameResult C_MatchBloxEngine::ProcessMsgs(void) { switch(message->sender) { + case MESSAGE_MENU: + int l_iAction; + int l_iGameMode; + menu_payload *l_pMsg1; + l_pMsg1 = (menu_payload*)message->payload; + + l_iAction = l_pMsg1->action; + + switch (l_iAction) + { + case ACTION_PAUSE: + Pause(); + break; + case ACTION_START: + l_iGameMode = l_pMsg1->gamemode; + StartGame(); + break; + case ACTION_RESUME: + Resume(); + break; + case ACTION_ABORT: + Abort(); + break; + } + break; case MESSAGE_INPUT_KEYBOARD: break; case MESSAGE_INPUT_MOUSE: break; case MESSAGE_INPUT_WIIMOTE: - input_payload_wiimote *l_pMsg; - l_pMsg = (input_payload_wiimote*)message->payload; + input_payload_wiimote *l_pMsg2; + l_pMsg2 = (input_payload_wiimote*)message->payload; + switch (m_State) { case ES_GET_READY: - if (l_pMsg->btns & WIIMOTE_BUTTON_A && - l_pMsg->btns & WIIMOTE_BUTTON_B && - l_pMsg->posDataValid) + if (l_pMsg2->btns & WIIMOTE_BUTTON_A && + l_pMsg2->btns & WIIMOTE_BUTTON_B && + l_pMsg2->posDataValid) { //the 3d mouse position data is valid and A+B are pressed //init the z depth and start the game - m_dInitialWiimoteDist = l_pMsg->Zdist; + m_dInitialWiimoteDist = l_pMsg2->Zdist; if (!StartGame()) { l_Result = GR_ERROR; @@ -112,7 +139,7 @@ GameResult C_MatchBloxEngine::ProcessMsgs(void) break; case ES_FINISHED: - if (l_pMsg->btns & WIIMOTE_BUTTON_ALL) + if (l_pMsg2->btns & WIIMOTE_BUTTON_ALL) { //any button is pressed //delete session and return GAME_FINISHED @@ -127,16 +154,16 @@ GameResult C_MatchBloxEngine::ProcessMsgs(void) break; default: - if (l_pMsg->posDataValid) + if (l_pMsg2->posDataValid) { m_uiLastPosValid = m_uiCurrentTime; Vect3D_t l_WorldPos; - if (l_pMsg->btns & WIIMOTE_BUTTON_A) + if (l_pMsg2->btns & WIIMOTE_BUTTON_A) { int i = 0; //debug break } - if (ConvertWiimoteToWorld(l_pMsg, &l_WorldPos)) + if (ConvertWiimoteToWorld(l_pMsg2, &l_WorldPos)) { CursorMove(l_WorldPos); } @@ -740,4 +767,4 @@ void C_MatchBloxEngine::GameFinished() //save session results to database -} \ No newline at end of file +} diff --git a/matchblox/engine/C_MatchBloxEngine.h b/matchblox/engine/C_MatchBloxEngine.h index 511db5a..4e5fcf3 100644 --- a/matchblox/engine/C_MatchBloxEngine.h +++ b/matchblox/engine/C_MatchBloxEngine.h @@ -33,7 +33,7 @@ enum EngineState ES_GET_READY, //game initialised, waiting for start signal from player ES_PLAYING_GRAB_BLOCK, //no block in hand -> grab floating block ES_PLAYING_PUT_BLOCK, //block in hand -> put block in box - ES_PAUSED, //pause... + ES_PAUSED, //pause... -> menu ES_FINISHED //finished -> show score and goto init }; diff --git a/matchblox/lib/WiiYourself!.lib b/matchblox/lib/WiiYourself!.lib index d6aaa00..0af7d02 100644 Binary files a/matchblox/lib/WiiYourself!.lib and b/matchblox/lib/WiiYourself!.lib differ diff --git a/matchblox/main.cpp b/matchblox/main.cpp index ce16470..3e54784 100644 --- a/matchblox/main.cpp +++ b/matchblox/main.cpp @@ -12,11 +12,8 @@ #include #include -#include #include -#include "message_queue.h" -#include "message_input.h" #include "typedefs.h" #include "menu.h" #include "textfile.h" @@ -145,10 +142,10 @@ void init_gl(void) void idle_func(void) { struct input_payload_wiimote wiimote_payload; + struct messageq_s message; g_GameState.m_pWiimote[0]->FillWiimoteMsgPayload(wiimote_payload, 205.0); // << should be a sensor bar led distance - struct messageq_s message; message.recipient = MESSAGE_MENU | MESSAGE_RENDERER; message.sender = MESSAGE_INPUT_WIIMOTE; message.payload = &wiimote_payload; @@ -156,9 +153,9 @@ void idle_func(void) messageq_send(&message); g_pEngine->ProcessMsgs(); - + //call engine idle func - MenuRun(); + MenuProcessMessage(); glutPostRedisplay(); } diff --git a/matchblox/matchblox.vcproj b/matchblox/matchblox.vcproj index 2c741d1..93a93c5 100644 --- a/matchblox/matchblox.vcproj +++ b/matchblox/matchblox.vcproj @@ -46,7 +46,7 @@ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_WIIYOURSELF;G_OS_WIN32" MinimalRebuild="true" BasicRuntimeChecks="3" - RuntimeLibrary="3" + RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="true" @@ -228,6 +228,10 @@ > + + diff --git a/matchblox/menu/button.c b/matchblox/menu/button.c index 36d1b90..c38bbfe 100644 --- a/matchblox/menu/button.c +++ b/matchblox/menu/button.c @@ -19,7 +19,7 @@ #include "font.h" -struct ButtonStruct ButtonCreate(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId) +struct ButtonStruct ButtonCreate(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId, void (*f_fpFunc)(void)) { struct ButtonStruct l_sButton; @@ -31,6 +31,7 @@ struct ButtonStruct ButtonCreate(int f_iXPos, int f_iYPos, int f_iWidth, int f_i l_sButton.m_iWidth = f_iWidth; l_sButton.m_iGroup = f_iGroup; l_sButton.m_iId = f_iId; + l_sButton.m_fpFunc = f_fpFunc; // copy title memset(&l_sButton.m_pcTitle, 0, sizeof(l_sButton.m_pcTitle)); @@ -212,6 +213,18 @@ void ButtonRadioRender(struct ButtonStruct *f_sButton) } // ButtonRadioRender +void ButtonLabelRender(struct ButtonStruct *f_sButton) +{ + struct ColorStruct l_sColor = {0, 0, 0}; //{0.2, 0.4, 0.8}; + + glPrint(f_sButton->m_iXPos, + f_sButton->m_iYPos, + f_sButton->m_pcTitle, + l_sColor); + +} // ButtonLabelRender + + void ButtonRender(struct ButtonStruct *f_sButton) { int l_iType = f_sButton->m_iType; @@ -226,6 +239,10 @@ void ButtonRender(struct ButtonStruct *f_sButton) ButtonRadioRender(f_sButton); break; + case BUTTON_LABEL: + ButtonLabelRender(f_sButton); + break; + default: break; } @@ -326,3 +343,11 @@ void ButtonDisable(struct ButtonStruct *f_sButton) f_sButton->m_bPressed = FALSE; } // ButtonDisable + +void ButtonExecute(struct ButtonStruct *f_sButton) +{ + if (f_sButton->m_fpFunc) + { + f_sButton->m_fpFunc(); + } +} // ButtonExecute \ No newline at end of file diff --git a/matchblox/menu/button.h b/matchblox/menu/button.h index d8f1fe5..6ee5388 100644 --- a/matchblox/menu/button.h +++ b/matchblox/menu/button.h @@ -8,16 +8,17 @@ #define BUTTON_CLICK_HEIGHT 49 struct ButtonStruct { - int m_iXPos; // x positie - int m_iYPos; // y positie - int m_iCenterWidth; // breedte van middenstuk - int m_iWidth; // totale breedte - int m_iHeight; // totale hoogte - int m_bPressed; // pressed or not - int m_bHover; // mouse hovering or not - int m_iType; // button type - int m_iGroup; // group id for radio buttons - int m_iId; // button identifier + int m_iXPos; // x positie + int m_iYPos; // y positie + int m_iCenterWidth; // breedte van middenstuk + int m_iWidth; // totale breedte + int m_iHeight; // totale hoogte + int m_bPressed; // pressed or not + int m_bHover; // mouse hovering or not + int m_iType; // button type + int m_iGroup; // group id for radio buttons + int m_iId; // button identifier + void (*m_fpFunc)(void); // function pointer // button caption/title char m_pcTitle[BUTTON_MAX_TITLE]; @@ -30,7 +31,8 @@ struct ButtonStruct { enum ButtonType { BUTTON_CLICK, - BUTTON_RADIO + BUTTON_RADIO, + BUTTON_LABEL }; enum ButtonGroup { @@ -41,7 +43,7 @@ enum ButtonGroup { BUTTON_GROUP4 }; -struct ButtonStruct ButtonCreate(int f_dXPos, int f_dYPos, int f_dCenterWidth, int f_dHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId); +struct ButtonStruct ButtonCreate(int f_iXPos, int f_iYPos, int f_iWidth, int f_iHeight, char *f_pcTitle, int f_iType, int f_iGroup, int f_iId, void (*f_fpFunc)(void)); void ButtonRender(struct ButtonStruct *f_sButton); void ButtonEnter(struct ButtonStruct *f_sButton); @@ -50,5 +52,7 @@ void ButtonPress(struct ButtonStruct *f_sButton); void ButtonRelease(struct ButtonStruct *f_sButton); void ButtonEnable(struct ButtonStruct *f_sButton); void ButtonDisable(struct ButtonStruct *f_sButton); +void ButtonExecute(struct ButtonStruct *f_sButton); + #endif diff --git a/matchblox/menu/menu.c b/matchblox/menu/menu.c index cb9573c..fc3f166 100644 --- a/matchblox/menu/menu.c +++ b/matchblox/menu/menu.c @@ -1,398 +1,436 @@ -#ifdef G_OS_WIN32 - #define WIN32_LEAN_AND_MEAN 1 - #include -#else - #define FALSE 0 - #define TRUE !FALSE -#endif - -#include -#include - - -#include "message_queue.h" -#include "message_input.h" - -#include "menu.h" -#include "button.h" -#include "font.h" - -#define MENU_MAX_BUTTONS 16 - -enum MenuState { - MENU_OFF, - MENU_MAIN, - MENU_START, - MENU_OPTIONS -}; - -struct MenuStruct { - enum MenuState m_iMenuId; - int m_iButtonCount; - struct ButtonStruct m_sButtons[MENU_MAX_BUTTONS]; -}; - -struct MenuStruct g_sMenuOff; // definition of the menu when it's disabled (empty menu) -struct MenuStruct g_sMenuMain; // definition of the main menu -struct MenuStruct g_sMenuStart; // definition of the start menu -struct MenuStruct g_sMenuOptions; // definition of the options menu -struct MenuStruct *g_pCurMenu; // current menu - -struct BitmapStruct g_sCursorImage; // bitmap struct of the cursor - -int g_iWinWidth; -int g_iWinHeight; - -int g_iXPos; // last cursor pos -int g_iYPos; - - -void MenuEnableGroup(int f_iGroup) -{ - struct ButtonStruct l_sButton; - int l_iType, l_iGroup; - int i = 0; - - // enable first radio button in this group - while (i < g_pCurMenu->m_iButtonCount) - { - l_sButton = g_pCurMenu->m_sButtons[i]; - l_iType = l_sButton.m_iType; - l_iGroup = l_sButton.m_iGroup; - - if (l_iType == BUTTON_RADIO && l_iGroup == f_iGroup) - { - ButtonEnable(&g_pCurMenu->m_sButtons[i]); - return; - } - - i++; - } - -} // MenuEnableGroup - - -void MenuAddButton(int f_dXPos, int f_dYPos, int f_dWidth, int f_dHeight, char *f_pcTitle, int f_iType, int f_iGroup) -{ - int i = g_pCurMenu->m_iButtonCount; - - if (i > MENU_MAX_BUTTONS - 1) - { - // return - } - else - { - // create the button with the right parameters - g_pCurMenu->m_sButtons[i] = ButtonCreate(f_dXPos, f_dYPos, f_dWidth, f_dHeight, f_pcTitle, f_iType, f_iGroup, i); - g_pCurMenu->m_iButtonCount = i + 1; - } -} // MenuAddButton - - -void MenuClear(void) -{ - g_pCurMenu->m_iButtonCount = 0; - memset(&g_pCurMenu->m_sButtons, 0, sizeof(g_pCurMenu->m_sButtons)); - -} // MenuClear - - -void MenuBuild (void) -{ - int l_iMenuId = g_pCurMenu->m_iMenuId; - - switch (l_iMenuId) - { - default: - case MENU_OFF: - // no buttons - break; - - case MENU_MAIN: - MenuAddButton(200, 150, 256, 128, "START", BUTTON_CLICK, BUTTON_NO_GROUP); - break; - - case MENU_START: - MenuAddButton(50, 50, 250, 64, "Button 1", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(50, 150, 250, 64, "Button 2", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(350, 50, 64, 64, "Radio 1", BUTTON_RADIO, BUTTON_GROUP1); - MenuAddButton(350, 150, 64, 64, "Radio 2", BUTTON_RADIO, BUTTON_GROUP1); - MenuEnableGroup(BUTTON_GROUP1); - - MenuAddButton(50, 250, 256, 64, "Button 3", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(50, 350, 256, 64, "Button 4", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(350, 250, 64, 64, "Radio A", BUTTON_RADIO, BUTTON_GROUP2); - MenuAddButton(350, 350, 64, 64, "Radio B", BUTTON_RADIO, BUTTON_GROUP2); - MenuEnableGroup(BUTTON_GROUP2); - break; - - case MENU_OPTIONS: - MenuAddButton(50, 150, 250, 64, "Start", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(50, 250, 250, 64, "Back", BUTTON_CLICK, BUTTON_NO_GROUP); - MenuAddButton(350, 150, 64, 64, "Try first!", BUTTON_RADIO, BUTTON_GROUP1); - MenuAddButton(350, 250, 64, 64, "10 games", BUTTON_RADIO, BUTTON_GROUP1); - MenuEnableGroup(BUTTON_GROUP1); - break; - } - -} // MenuBuild - - -void MenuNext(void) -{ - int l_iMenuId = g_pCurMenu->m_iMenuId; - - l_iMenuId = (l_iMenuId + 1) % 4; - - switch (l_iMenuId) - { - default: - case MENU_OFF: g_pCurMenu = &g_sMenuOff; break; - case MENU_MAIN: g_pCurMenu = &g_sMenuMain; break; - case MENU_START: g_pCurMenu = &g_sMenuStart; break; - case MENU_OPTIONS: g_pCurMenu = &g_sMenuOptions; break; - } - -} // MenuNext - - -void MenuInit(int f_iWinWidth, int f_iWinHeight) -{ - // init menu props - g_iWinWidth = f_iWinWidth; - g_iWinHeight = f_iWinHeight; - g_iXPos = -100; - g_iYPos = -100; - - // init main off - g_sMenuOff.m_iMenuId = MENU_OFF; - g_pCurMenu = &g_sMenuOff; - MenuBuild(); - - // init main menu - g_sMenuMain.m_iMenuId = MENU_MAIN; - g_pCurMenu = &g_sMenuMain; - MenuBuild(); - - // init start menu - g_sMenuStart.m_iMenuId = MENU_START; - g_pCurMenu = &g_sMenuStart; - MenuBuild(); - - // init options menu - g_sMenuOptions.m_iMenuId = MENU_OPTIONS; - g_pCurMenu = &g_sMenuOptions; - MenuBuild(); - - // init font - FontInit(f_iWinWidth, f_iWinHeight); - - g_pCurMenu = &g_sMenuOff; - - // load cursor image - g_sCursorImage = BitmapLoad("img/cursor.bmp"); - -} // MenuInit - - -void MenuRender(void) -{ - int i = 0; - - glClearColor(0.9, 0.9, 0.9, 1); - - glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - - glLoadIdentity(); - glOrtho(0, g_iWinWidth, g_iWinHeight, 0, 0, 1); - glMatrixMode(GL_MODELVIEW); - - glEnable(GL_BLEND); - - if (g_pCurMenu->m_iMenuId != MENU_OFF) - { - glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); - - glColor3f(0.6, 0.6, 0.7); - glBegin(GL_QUADS); - glVertex2i(0, 0); - glVertex2i(0, g_iWinHeight); - glVertex2i(g_iWinWidth, g_iWinHeight); - glVertex2i(g_iWinWidth, 0); - glEnd(); - } - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // render the buttons of the current menu - for (i; i < g_pCurMenu->m_iButtonCount; i++) - { - glColor4d(1, 1, 1, 1); - ButtonRender(&g_pCurMenu->m_sButtons[i]); - } - - // render cursor - glColor4d(1, 1, 1, 1); - BitmapRender(g_iXPos, - g_iYPos, - 64, //g_sCursorImage.m_iWidth, - 64, //g_sCursorImage.m_iHeight, - g_sCursorImage.m_iImageId); - - glDisable(GL_BLEND); - - //restore the previous projection matrix - glMatrixMode(GL_PROJECTION); - - glPopMatrix(); - - glPopAttrib(); -} // MenuRender - - -void MenuRun(void) -{ - struct messageq_s *message; - struct input_payload_keyboard *payload; - - message = messageq_get(MESSAGE_MENU); - if (message) { - payload = message->payload; - //printf("got a message! %c\n", (unsigned char)payload->key); - switch (payload->key) { - //default: - case ' ': - MenuNext(); - break; - case '0': - g_pCurMenu = &g_sMenuOff; - break; - case '1': - g_pCurMenu = &g_sMenuMain; - break; - case '2': - g_pCurMenu = &g_sMenuStart; - break; - case '3': - g_pCurMenu = &g_sMenuOptions; - break; - } - } -} - - -int MenuCollision(struct ButtonStruct *f_sButton, int f_iXPos, int f_iYPos) -{ - int l_bCollision; - int l_iButtonX, l_iButtonY; - int l_iButtonWidth, l_iButtonHeight; - - l_iButtonX = f_sButton->m_iXPos; - l_iButtonY = f_sButton->m_iYPos; - l_iButtonWidth = f_sButton->m_iWidth; - l_iButtonHeight = f_sButton->m_iHeight; - - l_bCollision = f_iXPos >= l_iButtonX; - l_bCollision &= f_iYPos >= l_iButtonY; - l_bCollision &= f_iXPos <= l_iButtonX + l_iButtonWidth; - l_bCollision &= f_iYPos <= l_iButtonY + l_iButtonHeight; - - if (l_bCollision) return TRUE; - return FALSE; - -} // MenuCollision - - -void MenuMouseClick(int f_iGlutButton, int f_iGlutState, int f_iXPos, int f_iYPos) -{ - int i = 0; - int l_iXPos, l_iYPos; - int l_iWidth, l_iHeight; - int l_iType, l_iId, l_iGroup; - struct ButtonStruct l_sButton; - - // button released - if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_UP) - { - // post a button released event to all buttons - for (i; i < g_pCurMenu->m_iButtonCount; i++) - { - l_iType = g_pCurMenu->m_sButtons[i].m_iType; - ButtonRelease(&g_pCurMenu->m_sButtons[i]); - } - } - - // check if any button needs attention from the mouse - i = g_pCurMenu->m_iButtonCount; - for (i; i >= 0; i--) - { - l_sButton = g_pCurMenu->m_sButtons[i]; - l_iXPos = l_sButton.m_iXPos; - l_iYPos = l_sButton.m_iYPos; - l_iWidth = l_sButton.m_iWidth; - l_iHeight = l_sButton.m_iHeight; - l_iType = l_sButton.m_iType; - l_iId = l_sButton.m_iId; - l_iGroup = l_sButton.m_iGroup; - - if (MenuCollision(&l_sButton, f_iXPos, f_iYPos)) - { - // button pressed? - if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_DOWN) - { - ButtonPress(&g_pCurMenu->m_sButtons[i]); - - if (l_iType == BUTTON_RADIO) - { - i = 0; - while (i < g_pCurMenu->m_iButtonCount) - { - - if (l_iId != g_pCurMenu->m_sButtons[i].m_iId && - l_iType == g_pCurMenu->m_sButtons[i].m_iType && - l_iGroup == g_pCurMenu->m_sButtons[i].m_iGroup) - { - ButtonDisable(&g_pCurMenu->m_sButtons[i]); - } - i++; - } - } - - return; - } - } - } - -} // MenuMouseClick - - -void MenuMouseMove(int f_iXPos, int f_iYPos) -{ - int i = 0; - struct ButtonStruct l_sButton; - - g_iXPos = f_iXPos; - g_iYPos = f_iYPos; - - // check if any button needs attention from the mouse - for (i; i < g_pCurMenu->m_iButtonCount; i++) - { - l_sButton = g_pCurMenu->m_sButtons[i]; - - if (MenuCollision(&l_sButton, f_iXPos, f_iYPos)) - { - ButtonEnter(&g_pCurMenu->m_sButtons[i]); - } - else // mouse leaves button - { - ButtonExit(&g_pCurMenu->m_sButtons[i]); - } - } - -} // MenuMouseMove - +#ifdef G_OS_WIN32 + #define WIN32_LEAN_AND_MEAN 1 + #include +#else + #define FALSE 0 + #define TRUE !FALSE +#endif + +#include +#include + +#include "message_queue.h" +#include "menu_msg.h" + +#include "message_input.h" +#include "menu.h" +#include "button.h" +#include "font.h" + +#define MENU_MAX_BUTTONS 16 + +enum MenuState { + MENU_OFF, + MENU_MAIN, + MENU_START, + MENU_OPTIONS +}; + +struct MenuStruct { + enum MenuState m_iMenuId; + int m_iButtonCount; + struct ButtonStruct m_sButtons[MENU_MAX_BUTTONS]; +}; + +struct MenuStruct g_sMenuOff; // definition of the menu when it's disabled (empty menu) +struct MenuStruct g_sMenuMain; // definition of the main menu +struct MenuStruct g_sMenuStart; // definition of the start menu +struct MenuStruct g_sMenuOptions; // definition of the options menu +struct MenuStruct *g_pCurMenu; // current menu + +struct BitmapStruct g_sCursorImage; // bitmap struct of the cursor + +int g_iWinWidth; +int g_iWinHeight; + +int g_iXPos; // last cursor pos +int g_iYPos; + + +void MenuEnableGroup(int f_iGroup) +{ + struct ButtonStruct l_sButton; + int l_iType, l_iGroup; + int i = 0; + + // enable first radio button in this group + while (i < g_pCurMenu->m_iButtonCount) + { + l_sButton = g_pCurMenu->m_sButtons[i]; + l_iType = l_sButton.m_iType; + l_iGroup = l_sButton.m_iGroup; + + if (l_iType == BUTTON_RADIO && l_iGroup == f_iGroup) + { + ButtonEnable(&g_pCurMenu->m_sButtons[i]); + return; + } + + i++; + } + +} // MenuEnableGroup + + +void MenuAddButton(int f_dXPos, int f_dYPos, int f_dWidth, int f_dHeight, char *f_pcTitle, int f_iType, int f_iGroup, void (*f_fpFunc)(void)) +{ + int i = g_pCurMenu->m_iButtonCount; + + if (i > MENU_MAX_BUTTONS - 1) + { + // return + } + else + { + // create the button with the right parameters + g_pCurMenu->m_sButtons[i] = ButtonCreate(f_dXPos, f_dYPos, f_dWidth, f_dHeight, f_pcTitle, f_iType, f_iGroup, i, f_fpFunc); + g_pCurMenu->m_iButtonCount = i + 1; + } +} // MenuAddButton + + +void MenuAddLabel(int f_dXPos, int f_dYPos, char *f_pcTitle) +{ + MenuAddButton(f_dXPos, f_dYPos, 0, 0, f_pcTitle, BUTTON_LABEL, BUTTON_NO_GROUP, NULL); +} //MenuAddLabel + + +void MenuClear(void) +{ + g_pCurMenu->m_iButtonCount = 0; + memset(&g_pCurMenu->m_sButtons, 0, sizeof(g_pCurMenu->m_sButtons)); + +} // MenuClear + + +void MenuBuild (void) +{ + int l_iMenuId = g_pCurMenu->m_iMenuId; + + switch (l_iMenuId) + { + default: + case MENU_OFF: + // no buttons + break; + + case MENU_MAIN: + MenuAddLabel(200, 150, "Press A+B to begin"); + break; + + case MENU_START: + MenuAddLabel(50, 50, "Headtracking"); + MenuAddButton(150, 100, 64, 64, "On", BUTTON_RADIO, BUTTON_GROUP1, NULL); + MenuAddButton(350, 100, 64, 64, "Off", BUTTON_RADIO, BUTTON_GROUP1, NULL); + MenuEnableGroup(BUTTON_GROUP1); + + MenuAddLabel(50, 250, "Stereo vision"); + MenuAddButton(150, 300, 64, 64, "On", BUTTON_RADIO, BUTTON_GROUP2, NULL); + MenuAddButton(350, 300, 64, 64, "Off", BUTTON_RADIO, BUTTON_GROUP2, NULL); + MenuAddButton(350, 400, 256, 64, "Next", BUTTON_CLICK, BUTTON_NO_GROUP, MenuPostMessagePause); + MenuEnableGroup(BUTTON_GROUP2); + + //MenuAddButton(50, 350, 0, 0, "Box size", BUTTON_LABEL, BUTTON_NO_GROUP, NULL); + //MenuAddButton(50, 400, 64, 64, "Small", BUTTON_RADIO, BUTTON_GROUP3, NULL); + //MenuAddButton(150, 400, 64, 64, "Medium", BUTTON_RADIO, BUTTON_GROUP3, NULL); + //MenuAddButton(250, 400, 64, 64, "Large", BUTTON_RADIO, BUTTON_GROUP3, NULL); + //MenuEnableGroup(BUTTON_GROUP3); + break; + + case MENU_OPTIONS: + MenuAddButton(250, 150, 250, 64, "Abort", BUTTON_CLICK, BUTTON_NO_GROUP, MenuNext); + MenuAddButton(250, 250, 250, 64, "Recalibrate", BUTTON_CLICK, BUTTON_NO_GROUP, MenuNext); + MenuEnableGroup(BUTTON_GROUP1); + break; + } + +} // MenuBuild + + +void MenuNext(void) +{ + int l_iMenuId = g_pCurMenu->m_iMenuId; + + l_iMenuId = (l_iMenuId + 1) % 4; + + switch (l_iMenuId) + { + default: + case MENU_OFF: g_pCurMenu = &g_sMenuOff; break; + case MENU_MAIN: g_pCurMenu = &g_sMenuMain; break; + case MENU_START: g_pCurMenu = &g_sMenuStart; break; + case MENU_OPTIONS: g_pCurMenu = &g_sMenuOptions; break; + } + +} // MenuNext + + +void MenuInit(int f_iWinWidth, int f_iWinHeight) +{ + // init menu props + g_iWinWidth = f_iWinWidth; + g_iWinHeight = f_iWinHeight; + g_iXPos = -100; + g_iYPos = -100; + + // init main off + g_sMenuOff.m_iMenuId = MENU_OFF; + g_pCurMenu = &g_sMenuOff; + MenuBuild(); + + // init main menu + g_sMenuMain.m_iMenuId = MENU_MAIN; + g_pCurMenu = &g_sMenuMain; + MenuBuild(); + + // init start menu + g_sMenuStart.m_iMenuId = MENU_START; + g_pCurMenu = &g_sMenuStart; + MenuBuild(); + + // init options menu + g_sMenuOptions.m_iMenuId = MENU_OPTIONS; + g_pCurMenu = &g_sMenuOptions; + MenuBuild(); + + // init font + FontInit(f_iWinWidth, f_iWinHeight); + + //g_pCurMenu = &g_sMenuOff; + g_pCurMenu = &g_sMenuMain; + + // load cursor image + g_sCursorImage = BitmapLoad("img/cursor.bmp"); + +} // MenuInit + + +void MenuRender(void) +{ + int i = 0; + + glClearColor(0.9, 0.9, 0.9, 1); + + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + glOrtho(0, g_iWinWidth, g_iWinHeight, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + + glEnable(GL_BLEND); + + if (g_pCurMenu->m_iMenuId != MENU_OFF) + { + glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); + + glColor3f(0.6, 0.6, 0.7); + glBegin(GL_QUADS); + glVertex2i(0, 0); + glVertex2i(0, g_iWinHeight); + glVertex2i(g_iWinWidth, g_iWinHeight); + glVertex2i(g_iWinWidth, 0); + glEnd(); + } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // render the buttons of the current menu + for (i; i < g_pCurMenu->m_iButtonCount; i++) + { + glColor4d(1, 1, 1, 1); + ButtonRender(&g_pCurMenu->m_sButtons[i]); + } + + if (g_pCurMenu->m_iMenuId != MENU_OFF) + { + // render cursor + glColor4d(1, 1, 1, 1); + BitmapRender(g_iXPos, + g_iYPos, + 64, //g_sCursorImage.m_iWidth, + 64, //g_sCursorImage.m_iHeight, + g_sCursorImage.m_iImageId); + } + + glDisable(GL_BLEND); + + //restore the previous projection matrix + glMatrixMode(GL_PROJECTION); + + glPopMatrix(); + + glPopAttrib(); +} // MenuRender + + +void MenuProcessMessage(void) +{ + struct messageq_s *message; + struct input_payload_wiimote *l_pMsg; + int l_iXPos, l_iYPos; + int l_iWidth, l_iHeight; + int i = 0; + + message = messageq_get(MESSAGE_MENU); + if (message) + { + switch(message->sender) + { + case MESSAGE_INPUT_KEYBOARD: + break; + case MESSAGE_INPUT_MOUSE: + break; + case MESSAGE_INPUT_WIIMOTE: + l_pMsg = (struct input_payload_wiimote*)message->payload; + + switch (g_pCurMenu->m_iMenuId) + { + case MENU_MAIN: + if (l_pMsg->btns & WIIMOTE_BUTTON_A && l_pMsg->btns & WIIMOTE_BUTTON_B) + { + MenuNext(); + } + break; + + default: + if (l_pMsg->posDataValid) + { + l_iWidth = glutGet(GLUT_WINDOW_WIDTH); + l_iHeight = glutGet(GLUT_WINDOW_HEIGHT); + l_iXPos = l_pMsg->relX * l_iWidth; + l_iYPos = l_iHeight - (l_pMsg->relY * l_iHeight); + + if (l_pMsg->btns & WIIMOTE_BUTTON_A) + { + MenuMouseClick(GLUT_LEFT_BUTTON, GLUT_DOWN, l_iXPos, l_iYPos); + } + else if (l_pMsg->btnsUp & WIIMOTE_BUTTON_A) + { + MenuMouseClick(GLUT_LEFT_BUTTON, GLUT_UP, l_iXPos, l_iYPos); + } + else + { + MenuMouseMove(l_iXPos, l_iYPos); + } + } + break; + break; + } + break; + } + } +} + + +int MenuCollision(struct ButtonStruct *f_sButton, int f_iXPos, int f_iYPos) +{ + int l_bCollision; + int l_iButtonX, l_iButtonY; + int l_iButtonWidth, l_iButtonHeight; + + l_iButtonX = f_sButton->m_iXPos; + l_iButtonY = f_sButton->m_iYPos; + l_iButtonWidth = f_sButton->m_iWidth; + l_iButtonHeight = f_sButton->m_iHeight; + + l_bCollision = f_iXPos >= l_iButtonX; + l_bCollision &= f_iYPos >= l_iButtonY; + l_bCollision &= f_iXPos <= l_iButtonX + l_iButtonWidth; + l_bCollision &= f_iYPos <= l_iButtonY + l_iButtonHeight; + + if (l_bCollision) return TRUE; + return FALSE; + +} // MenuCollision + + +void MenuMouseClick(int f_iGlutButton, int f_iGlutState, int f_iXPos, int f_iYPos) +{ + int i = 0; + int l_iType, l_iId, l_iGroup; + struct ButtonStruct l_sButton; + + // button released + if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_UP) + { + // post a button released event to all buttons + for (i; i < g_pCurMenu->m_iButtonCount; i++) + { + l_iType = g_pCurMenu->m_sButtons[i].m_iType; + ButtonRelease(&g_pCurMenu->m_sButtons[i]); + + if (MenuCollision(&g_pCurMenu->m_sButtons[i], f_iXPos, f_iYPos)) + { + ButtonExecute(&g_pCurMenu->m_sButtons[i]); + } + } + } + + // check if any button needs attention from the mouse + i = g_pCurMenu->m_iButtonCount; + for (i; i >= 0; i--) + { + l_sButton = g_pCurMenu->m_sButtons[i]; + l_iType = l_sButton.m_iType; + l_iId = l_sButton.m_iId; + l_iGroup = l_sButton.m_iGroup; + + if (MenuCollision(&l_sButton, f_iXPos, f_iYPos)) + { + // button pressed? + if (f_iGlutButton == GLUT_LEFT_BUTTON && f_iGlutState == GLUT_DOWN) + { + ButtonPress(&g_pCurMenu->m_sButtons[i]); + + if (l_iType == BUTTON_RADIO) + { + i = 0; + while (i < g_pCurMenu->m_iButtonCount) + { + if (l_iId != g_pCurMenu->m_sButtons[i].m_iId && + l_iType == g_pCurMenu->m_sButtons[i].m_iType && + l_iGroup == g_pCurMenu->m_sButtons[i].m_iGroup) + { + ButtonDisable(&g_pCurMenu->m_sButtons[i]); + } + i++; + } + } + + return; + } + } + } + +} // MenuMouseClick + + +void MenuMouseMove(int f_iXPos, int f_iYPos) +{ + int i = 0; + struct ButtonStruct l_sButton; + + g_iXPos = f_iXPos; + g_iYPos = f_iYPos; + + // check if any button needs attention from the mouse + for (i; i < g_pCurMenu->m_iButtonCount; i++) + { + l_sButton = g_pCurMenu->m_sButtons[i]; + + if (MenuCollision(&l_sButton, f_iXPos, f_iYPos)) + { + ButtonEnter(&g_pCurMenu->m_sButtons[i]); + } + else // mouse leaves button + { + ButtonExit(&g_pCurMenu->m_sButtons[i]); + } + } + +} // MenuMouseMove \ No newline at end of file diff --git a/matchblox/menu/menu.h b/matchblox/menu/menu.h index 656d259..6a54332 100644 --- a/matchblox/menu/menu.h +++ b/matchblox/menu/menu.h @@ -9,11 +9,10 @@ extern "C" { void MenuNext(void); void MenuInit(int f_iWinWidth, int f_iWinHeight); void MenuRender(void); -void MenuRun(void); +void MenuProcessMessage(void); void MenuMouseClick(int button, int state, int x, int y); void MenuMouseMove(int x, int y); - #ifdef __cplusplus } #endif diff --git a/matchblox/menu/menu_msg.c b/matchblox/menu/menu_msg.c new file mode 100644 index 0000000..3a84543 --- /dev/null +++ b/matchblox/menu/menu_msg.c @@ -0,0 +1,63 @@ +#include "message_queue.h" +#include "message_input.h" +#include "menu_msg.h" + +void MenuPostMessage(struct menu_payload payload) +{ + struct messageq_s message; + + message.recipient = MESSAGE_RENDERER; + message.sender = MESSAGE_MENU; + message.payload = &payload; + message.payload_size = sizeof(struct menu_payload); + messageq_send(&message); + +} // MenuPostMessage + + +void MenuPostMessagePause(void) +{ + struct menu_payload payload; + + payload.action = ACTION_PAUSE; + payload.gamemode = 0; + + MenuPostMessage(payload); + +} // MenuPostMessagePause + + +void MenuPostMessageResume(void) +{ + struct menu_payload payload; + + payload.action = ACTION_RESUME; + payload.gamemode = 0; + + MenuPostMessage(payload); + +} // MenuPostMessageResume + + +void MenuPostMessageStart(void) +{ + struct menu_payload payload; + + payload.action = ACTION_START; + payload.gamemode = 0; + + MenuPostMessage(payload); + +} // MenuPostMessageStart + + +void MenuPostMessageAbort(void) +{ + struct menu_payload payload; + + payload.action = ACTION_ABORT; + payload.gamemode = 0; + + MenuPostMessage(payload); + +} // MenuPostMessageAbort \ No newline at end of file diff --git a/matchblox/menu/menu_msg.h b/matchblox/menu/menu_msg.h new file mode 100644 index 0000000..15dd423 --- /dev/null +++ b/matchblox/menu/menu_msg.h @@ -0,0 +1,23 @@ +#ifndef _CMENU_MSG_H +#define _CMENU_MSG_H + +struct menu_payload +{ + int action; + int gamemode; +}; + +enum game_actions +{ + ACTION_START = 0x0001, + ACTION_ABORT = 0x0002, + ACTION_PAUSE = 0x0004, + ACTION_RESUME = 0x0008 +}; + +void MenuPostMessagePause(void); +void MenuPostMessageResume(void); +void MenuPostMessageStart(void); +void MenuPostMessageAbort(void); + +#endif \ No newline at end of file -- cgit v0.12