summaryrefslogtreecommitdiffstats
path: root/matchblox/menu
diff options
context:
space:
mode:
authorOliver Schinagl <oliver@schinagl.nl>2008-05-14 11:56:06 (GMT)
committerOliver Schinagl <oliver@schinagl.nl>2008-05-14 11:56:06 (GMT)
commitd4d35970d88edccdd963e53ea3e11f702e1e2bab (patch)
treeaa3f522ef826752bf08e2396f70a3156e1b81e5b /matchblox/menu
parentab5d6fe55a31891ac8ad2949c31704e8245e116f (diff)
download2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.zip
2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.tar.gz
2iv55-d4d35970d88edccdd963e53ea3e11f702e1e2bab.tar.bz2
fix this
Diffstat (limited to 'matchblox/menu')
-rw-r--r--matchblox/menu/button.c328
-rw-r--r--matchblox/menu/button.h54
-rw-r--r--matchblox/menu/menu.c359
-rw-r--r--matchblox/menu/menu.h10
4 files changed, 751 insertions, 0 deletions
diff --git a/matchblox/menu/button.c b/matchblox/menu/button.c
new file mode 100644
index 0000000..d452fd0
--- /dev/null
+++ b/matchblox/menu/button.c
@@ -0,0 +1,328 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+#else
+ #define FALSE 0
+ #define TRUE !FALSE
+ #define max(a, b) (((a) > (b)) ? (a) : (b))
+
+#endif
+
+#include <string.h>
+
+#include <GL/gl.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "button.h"
+#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 l_sButton;
+
+ // copy parameters
+ l_sButton.m_iXPos = f_iXPos;
+ l_sButton.m_iYPos = f_iYPos;
+ l_sButton.m_iType = f_iType;
+ l_sButton.m_iHeight = f_iHeight;
+ l_sButton.m_iWidth = f_iWidth;
+ l_sButton.m_iGroup = f_iGroup;
+ l_sButton.m_iId = f_iId;
+
+ // copy title
+ memset(&l_sButton.m_pcTitle, 0, sizeof(l_sButton.m_pcTitle));
+ memcpy(l_sButton.m_pcTitle, f_pcTitle, strlen(f_pcTitle));
+
+ switch (f_iType)
+ {
+ case BUTTON_CLICK:
+ l_sButton.m_psImgNormal[0] = BitmapLoad("img/button_click_left.bmp");
+ l_sButton.m_psImgNormal[1] = BitmapLoad("img/button_click_center.bmp");
+ l_sButton.m_psImgNormal[2] = BitmapLoad("img/button_click_right.bmp");
+
+ l_sButton.m_psImgHover[0] = BitmapLoad("img/button_click_left_hover.bmp");
+ l_sButton.m_psImgHover[1] = BitmapLoad("img/button_click_center_hover.bmp");
+ l_sButton.m_psImgHover[2] = BitmapLoad("img/button_click_right_hover.bmp");
+
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[1], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[2], f_iHeight);
+
+ BitmapConvertWidth(&l_sButton.m_psImgHover[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[1], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[2], f_iHeight);
+
+ // calculate (center)width of image
+ l_sButton.m_iCenterWidth = max(f_iWidth - l_sButton.m_psImgNormal[0].m_iWidth - l_sButton.m_psImgNormal[2].m_iWidth, 0);
+ l_sButton.m_iWidth = l_sButton.m_iCenterWidth + l_sButton.m_psImgNormal[0].m_iWidth + l_sButton.m_psImgNormal[2].m_iWidth;
+ break;
+
+ case BUTTON_RADIO:
+ l_sButton.m_psImgNormal[0] = BitmapLoad("img/button_radio.bmp");
+ l_sButton.m_psImgHover[0] = BitmapLoad("img/button_radio_hover.bmp");
+ l_sButton.m_psImgPressed[0] = BitmapLoad("img/button_radio_pressed.bmp");
+
+ BitmapConvertWidth(&l_sButton.m_psImgNormal[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgHover[0], f_iHeight);
+ BitmapConvertWidth(&l_sButton.m_psImgPressed[0], f_iHeight);
+
+ l_sButton.m_iCenterWidth = 0;
+ l_sButton.m_iHeight = f_iHeight;
+ l_sButton.m_iWidth = f_iWidth;
+ break;
+
+ default:
+ break;
+ }
+
+ l_sButton.m_bPressed = FALSE;
+ l_sButton.m_bHover = FALSE;
+
+ return l_sButton;
+
+} // ButtonCreate
+
+
+void ButtonClickRender(struct ButtonStruct *f_sButton)
+{
+ char l_pcTitle[BUTTON_MAX_TITLE];
+ struct BitmapStruct *l_sImgButton;
+ int l_iImageIdLeft, l_iImageIdCenter, l_iImageIdRight;
+ int l_iLen, l_iXOffset, l_iYOffset, l_iWidth;
+ struct ColorStruct l_sColor = {0, 0, 0};
+
+ // copy button attributes
+ int l_iCnWdt = f_sButton->m_iCenterWidth;
+ int l_iHeight = f_sButton->m_iHeight;
+ int l_iXPos = f_sButton->m_iXPos;
+ int l_iYPos = f_sButton->m_iYPos;
+
+ if (f_sButton->m_bPressed)
+ {
+ glColor3d(0.8, 0.9, 1);
+ }
+ else
+ {
+ glColor3d(1, 1, 1);
+ }
+
+ // get the right image struct
+ if (f_sButton->m_bHover)
+ {
+ l_sImgButton = f_sButton->m_psImgHover;
+ }
+ else
+ {
+ l_sImgButton = f_sButton->m_psImgNormal;
+ }
+
+ // copy buttom images
+ l_iImageIdLeft = l_sImgButton[0].m_iImageId;
+ l_iImageIdCenter = l_sImgButton[1].m_iImageId;
+ l_iImageIdRight = l_sImgButton[2].m_iImageId;
+
+ // copy button title
+ memcpy(&l_pcTitle, f_sButton->m_pcTitle, strlen(f_sButton->m_pcTitle));
+
+ // render left side of button
+ l_iWidth = l_sImgButton[0].m_iWidth;
+ BitmapRender(l_iXPos,
+ l_iYPos,
+ l_iWidth + 1,
+ l_iHeight,
+ l_iImageIdLeft);
+
+ // render right side of button
+ l_iWidth = l_sImgButton[2].m_iWidth;
+ BitmapRender(l_iXPos + l_iCnWdt + l_iWidth - 1,
+ l_iYPos,
+ l_iWidth,
+ l_iHeight,
+ l_iImageIdRight);
+
+ // render center of button
+ if (l_iCnWdt > 0)
+ {
+ BitmapRender(l_iXPos + l_iWidth - 1,
+ l_iYPos,
+ l_iCnWdt + 1,
+ l_iHeight,
+ l_iImageIdCenter);
+ }
+
+ l_iLen = (int)strlen(f_sButton->m_pcTitle);
+ l_iXOffset = (int)(0.5 * f_sButton->m_iWidth - 0.5 * l_iLen * FONT_SPACING);
+ l_iYOffset = (int)(0.5 * f_sButton->m_iHeight - 0.5 * FONT_HEIGHT);
+
+ glPrint(f_sButton->m_iXPos + l_iXOffset,
+ f_sButton->m_iYPos + l_iYOffset,
+ f_sButton->m_pcTitle,
+ l_sColor);
+
+} // ButtonClickRender
+
+
+void ButtonRadioRender(struct ButtonStruct *f_sButton)
+{
+ struct BitmapStruct *l_sImgButton;
+ int l_iXOffset, l_iYOffset, l_iImageRadioId, l_iImageEnabledId;
+
+ // copy button attributes
+ int l_iWidth = f_sButton->m_iWidth;
+ int l_iHeight = f_sButton->m_iHeight;
+ int l_iXPos = f_sButton->m_iXPos;
+ int l_iYPos = f_sButton->m_iYPos;
+ struct ColorStruct l_sColor = {0.2, 0.4, 0.8};
+
+ // get the right image struct
+ if (f_sButton->m_bHover)
+ {
+ l_sImgButton = f_sButton->m_psImgHover;
+ }
+ else
+ {
+ l_sImgButton = f_sButton->m_psImgNormal;
+ }
+
+ l_iImageRadioId = l_sImgButton[0].m_iImageId;
+ l_iImageEnabledId = f_sButton->m_psImgPressed[0].m_iImageId;
+
+ glColor3d(1, 1, 1);
+
+ // render the radio button
+ BitmapRender(l_iXPos, l_iYPos, l_iWidth, l_iHeight, l_iImageRadioId);
+
+ // render the enable-dot if button is pressed
+ if (f_sButton->m_bPressed)
+ {
+ BitmapRender(l_iXPos, l_iYPos, l_iWidth, l_iHeight, l_iImageEnabledId);
+ }
+
+ l_iXOffset = (int)f_sButton->m_iWidth;
+ l_iYOffset = (int)(0.5 * f_sButton->m_iHeight - 0.5 * FONT_HEIGHT);
+
+ glPrint(f_sButton->m_iXPos + l_iXOffset,
+ f_sButton->m_iYPos + l_iYOffset,
+ f_sButton->m_pcTitle,
+ l_sColor);
+
+} // ButtonRadioRender
+
+
+void ButtonRender(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickRender(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ ButtonRadioRender(f_sButton);
+ break;
+
+ default:
+ break;
+ }
+
+} // ButtonRender
+
+
+void ButtonEnter(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bHover = TRUE;
+
+} // ButtonHover
+
+
+void ButtonExit(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bHover = FALSE;
+
+} // ButtonHover
+
+
+void ButtonClickPress(struct ButtonStruct *f_sButton)
+{
+ if (!f_sButton->m_bPressed) {
+ ButtonEnable(f_sButton);
+ }
+
+} // ButtonClickPress
+
+
+void ButtonRadioPress(struct ButtonStruct *f_sButton)
+{
+ int i = 0;
+
+ if (!f_sButton->m_bPressed)
+ {
+ ButtonEnable(f_sButton);
+ }
+
+} // ButtonClickPress
+
+
+void ButtonPress(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickPress(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ ButtonRadioPress(f_sButton);
+ break;
+
+ default:
+ break;
+ }
+
+} // ButtonPress
+
+
+void ButtonClickRelease(struct ButtonStruct *f_sButton)
+{
+ ButtonDisable(f_sButton);
+
+} // ButtonClickRelease
+
+
+void ButtonRelease(struct ButtonStruct *f_sButton)
+{
+ int l_iType = f_sButton->m_iType;
+
+ switch (l_iType)
+ {
+ case BUTTON_CLICK:
+ ButtonClickRelease(f_sButton);
+ break;
+
+ case BUTTON_RADIO:
+ default:
+ break;
+ }
+
+} // ButtonRelease
+
+
+void ButtonEnable(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bPressed = TRUE;
+
+} // ButtonEnable
+
+
+void ButtonDisable(struct ButtonStruct *f_sButton)
+{
+ f_sButton->m_bPressed = FALSE;
+
+} // ButtonDisable
diff --git a/matchblox/menu/button.h b/matchblox/menu/button.h
new file mode 100644
index 0000000..d8f1fe5
--- /dev/null
+++ b/matchblox/menu/button.h
@@ -0,0 +1,54 @@
+#ifndef _CBUTTON_H
+#define _CBUTTON_H
+
+#include "bitmap.h"
+
+#define BUTTON_MAX_TITLE 256
+#define BUTTON_MAX_IMGS 3
+#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
+
+ // button caption/title
+ char m_pcTitle[BUTTON_MAX_TITLE];
+
+ // button images
+ struct BitmapStruct m_psImgNormal[BUTTON_MAX_IMGS];
+ struct BitmapStruct m_psImgHover[BUTTON_MAX_IMGS];
+ struct BitmapStruct m_psImgPressed[BUTTON_MAX_IMGS];
+};
+
+enum ButtonType {
+ BUTTON_CLICK,
+ BUTTON_RADIO
+};
+
+enum ButtonGroup {
+ BUTTON_NO_GROUP,
+ BUTTON_GROUP1,
+ BUTTON_GROUP2,
+ BUTTON_GROUP3,
+ 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);
+
+void ButtonRender(struct ButtonStruct *f_sButton);
+void ButtonEnter(struct ButtonStruct *f_sButton);
+void ButtonExit(struct ButtonStruct *f_sButton);
+void ButtonPress(struct ButtonStruct *f_sButton);
+void ButtonRelease(struct ButtonStruct *f_sButton);
+void ButtonEnable(struct ButtonStruct *f_sButton);
+void ButtonDisable(struct ButtonStruct *f_sButton);
+
+#endif
diff --git a/matchblox/menu/menu.c b/matchblox/menu/menu.c
new file mode 100644
index 0000000..9276850
--- /dev/null
+++ b/matchblox/menu/menu.c
@@ -0,0 +1,359 @@
+#ifdef G_OS_WIN32
+ #define WIN32_LEAN_AND_MEAN 1
+ #include <windows.h>
+#else
+ #define FALSE 0
+ #define TRUE !FALSE
+#endif
+
+#include <string.h>
+#include <GL/gl.h>
+#include <GL/glut.h>
+#include <string.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;
+
+ // 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);
+
+ 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);
+
+ glColor3d(0.6, 0.6, 0.7);
+ glBegin(GL_TRIANGLE_STRIP);
+ glVertex2i(0, 0);
+ glVertex2i(g_iWinWidth, 0);
+ glVertex2i(0, g_iWinHeight);
+ glVertex2i(g_iWinWidth, g_iWinHeight);
+ 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
+ glColor3d(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();
+
+} // MenuRender
+
+
+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
+
diff --git a/matchblox/menu/menu.h b/matchblox/menu/menu.h
new file mode 100644
index 0000000..0b4e95f
--- /dev/null
+++ b/matchblox/menu/menu.h
@@ -0,0 +1,10 @@
+#ifndef _CMENU_H
+#define _CMENU_H
+
+void MenuNext(void);
+void MenuInit(int f_iWinWidth, int f_iWinHeight);
+void MenuRender(void);
+void MenuMouseClick(int button, int state, int x, int y);
+void MenuMouseMove(int x, int y);
+
+#endif