diff --git a/src/include/menus.h b/src/include/menus.h index 7eb9fa816..6a13d24d1 100644 --- a/src/include/menus.h +++ b/src/include/menus.h @@ -123,6 +123,15 @@ typedef struct _menuitem_ { struct { void (*draw)(struct _menuitem_ *); } drawfunc; + struct { + unsigned char *buffer; + unsigned xsize; + unsigned ysize; + MenuButtonId button; + void (*action)(struct _menuitem_ *, int); /* for key */ + int nch; + int maxch; + } input; /// ... add here ... } d; @@ -134,6 +143,7 @@ typedef struct _menuitem_ { #define MI_TYPE_LISTBOX 4 #define MI_TYPE_VSLIDER 5 #define MI_TYPE_DRAWFUNC 6 +#define MI_TYPE_INPUT 7 /// for MI_TYPE_TEXT #define MI_TFLAGS_CENTERED 1 @@ -168,7 +178,8 @@ typedef struct _menus_ { #define MENU_SCEN_SELECT 3 #define MENU_PRG_START 4 #define MENU_CUSTOM_GAME_SETUP 5 -#define MENU_MAX 5 /// highest available menu id (for ccl) +#define MENU_ENTER_NAME 6 +#define MENU_MAX 6 /// highest available menu id (for ccl) /// FIXME: FILL IN THIS TABLE!!!! diff --git a/src/ui/menus.cpp b/src/ui/menus.cpp index 5bbae4c6a..0e3675b48 100644 --- a/src/ui/menus.cpp +++ b/src/ui/menus.cpp @@ -55,6 +55,9 @@ local void GameMenuEnd(void); local void GameMenuReturn(void); local void StartMenusSetBackground(Menuitem *mi); +local void NameLineDrawFunc(Menuitem *mi); +local void EnterNameAction(Menuitem *mi, int key); +local void EnterNameCancel(void); local void SinglePlayerGameMenu(void); local void MultiPlayerGameMenu(void); @@ -213,8 +216,8 @@ local Menuitem ScenSelectMenuItems[] = { ** Items for the Prg Start Menu */ local Menuitem PrgStartMenuItems[] = { - { MI_TYPE_TEXT, 640/2, 440, 0, GameFont, NULL, NULL, - { text:{ NameLine, MI_TFLAGS_CENTERED} } }, + { MI_TYPE_DRAWFUNC, 0, 0, 0, GameFont, NULL, NULL, + { drawfunc:{ NameLineDrawFunc } } }, { MI_TYPE_BUTTON, 208, 320, 0, LargeFont, StartMenusSetBackground, NULL, { button:{ "~!Single Player Game", 224, 27, MBUTTON_GM_FULL, SinglePlayerGameMenu, 's'} } }, { MI_TYPE_BUTTON, 208, 320 + 36, MenuButtonDisabled, LargeFont, NULL, NULL, @@ -297,6 +300,20 @@ local Menuitem CustomGameMenuItems[] = { { pulldown:{ cgtssoptions, 152, 20, MBUTTON_PULLDOWN, CustomGameTSSAction, 5, 0, 0, 0} } }, }; +/** +** Items for the Enter Name Menu +*/ +local Menuitem EnterNameMenuItems[] = { + { MI_TYPE_TEXT, 144, 11, 0, GameFont, NULL, NULL, + { text:{ "Enter your name:", MI_TFLAGS_CENTERED} } }, + { MI_TYPE_INPUT, 40, 38, 0, GameFont, NULL, NULL, + { input:{ NULL, 212, 20, MBUTTON_PULLDOWN, EnterNameAction, 0, 0} } }, + { MI_TYPE_BUTTON, 24, 80, MenuButtonSelected, LargeFont, NULL, NULL, + { button:{ "~!OK", 106, 27, MBUTTON_GM_HALF, EndMenu, 'o'} } }, + { MI_TYPE_BUTTON, 154, 80, 0, LargeFont, NULL, NULL, + { button:{ "~!Cancel", 106, 27, MBUTTON_GM_HALF, EnterNameCancel, 'c'} } }, +}; + /** ** Menus */ @@ -355,6 +372,15 @@ global Menu Menus[] = { 3, 15, CustomGameMenuItems }, + { + /// Enter Name Menu + (640-288)/2, + 260, + 288, 128, + ImagePanel4, + 2, 4, + EnterNameMenuItems + }, }; /*---------------------------------------------------------------------------- @@ -605,6 +631,50 @@ local void DrawVSlider(Menuitem *mi, unsigned mx, unsigned my) } +/** +** Draw input 'button' on menu mx, my +** +** @param mi menuitem pointer +** @param mx menu X display position (offset) +** @param my menu Y display position (offset) +*/ +local void DrawInput(Menuitem *mi, unsigned mx, unsigned my) +{ + int nc, rc; + char *text; + unsigned flags = mi->flags; + MenuButtonId rb = mi->d.input.button; + unsigned w, h, x, y; + + x = mx+mi->xofs; + y = my+mi->yofs; + w = mi->d.input.xsize; + h = mi->d.input.ysize; + + GetDefaultTextColors(&nc, &rc); + if (flags&MenuButtonDisabled) { + rb--; + SetDefaultTextColors(FontGrey,FontGrey); + } + + PushClipping(); + SetClipping(0,0,x+w,VideoHeight); + VideoDrawClip(MenuButtonGfx.Sprite, rb, x-1, y-1); + PopClipping(); + text = mi->d.input.buffer; + if (text) { + DrawText(x+2,y+2,mi->font,text); + } + if (flags&MenuButtonSelected) { + if (flags&MenuButtonDisabled) { + VideoDrawRectangleClip(ColorGray,x-2,y-2,w,h); + } else { + VideoDrawRectangleClip(ColorYellow,x-2,y-2,w,h); + } + } + SetDefaultTextColors(nc,rc); +} + /** ** Draw menu 'menu' @@ -665,6 +735,9 @@ global void DrawMenu(int MenuId) (*mi->d.drawfunc.draw)(mi); } break; + case MI_TYPE_INPUT: + DrawInput(mi,menu->x,menu->y); + break; default: break; } @@ -687,6 +760,16 @@ local void StartMenusSetBackground(Menuitem *mi __attribute__((unused))) DisplayPicture("graphic/interface/Menu background without title.png"); } +local void NameLineDrawFunc(Menuitem *mi __attribute__((unused))) +{ + int nc, rc; + + GetDefaultTextColors(&nc, &rc); + SetDefaultTextColors(rc, rc); + DrawTextCentered(640/2, 440, GameFont, NameLine); + SetDefaultTextColors(nc, rc); +} + local void GameMenuReturn(void) { EndMenu(); @@ -740,10 +823,43 @@ local void SinglePlayerGameMenu(void) } } +local void EnterNameCancel(void) +{ + EnterNameMenuItems[1].d.input.nch = 0; + EndMenu(); +} + +local void EnterNameAction(Menuitem *mi, int key) +{ + if (mi->d.input.nch == 0) { + mi[1].flags = MenuButtonDisabled; + } else { + mi[1].flags &= ~MenuButtonDisabled; + if (key == 10 || key == 13) { + EndMenu(); + } + } +} + local void MultiPlayerGameMenu(void) { - // ProcessMenu( ??? , 1); - Exit(0); + char NameBuf[32]; + + StartMenusSetBackground(NULL); + Invalidate(); + EnterNameMenuItems[1].d.input.buffer = NameBuf; + strcpy(NameBuf, "Anonymous~!_"); + EnterNameMenuItems[1].d.input.nch = strlen(NameBuf) - 3; + EnterNameMenuItems[1].d.input.maxch = 15; + ProcessMenu(MENU_ENTER_NAME, 1); + DestroyCursorBackground(); + StartMenusSetBackground(NULL); + if (EnterNameMenuItems[1].d.input.nch == 0) { + return; + } + + NameBuf[EnterNameMenuItems[1].d.input.nch] = 0; // Now finally here is the name + // Here we really go... } @@ -1217,8 +1333,50 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ Menuitem *mi; Menu *menu = Menus + CurrentMenu; - i = menu->nitems; + if (CurrentMenu < 0) { + return 0; + } + + if (MenuButtonCurSel != -1 && menu->items[MenuButtonCurSel].mitype == MI_TYPE_INPUT) { + mi = menu->items + MenuButtonCurSel; + if (!(mi->flags & MenuButtonDisabled)) { +inkey: + if (key < 0) { + key &= 0xFF; + } + if (key >= 0x80 && key < 0x100) { + // FIXME ARI: ISO->WC2 Translation here! + key = 0; + } + switch(key) { + case '\b': case '\177': + if (mi->d.input.nch > 0) { + strcpy(mi->d.input.buffer + (--mi->d.input.nch), "~!_"); + MustRedraw |= RedrawMenu; + } + break; + case 9: + goto normkey; + default: + if (key >= 32 && key < 0x100) { + if (mi->d.input.nch < mi->d.input.maxch) { + mi->d.input.buffer[mi->d.input.nch++] = key; + strcpy(mi->d.input.buffer + mi->d.input.nch, "~!_"); + MustRedraw |= RedrawMenu; + } + } + break; + } + if (mi->d.input.action) { + (*mi->d.input.action)(mi, key); + } + return 1; + } + } + +normkey: mi = menu->items; + i = menu->nitems; while (i--) { switch (mi->mitype) { case MI_TYPE_BUTTON: @@ -1334,6 +1492,7 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ case MI_TYPE_PULLDOWN: case MI_TYPE_LISTBOX: case MI_TYPE_VSLIDER: + case MI_TYPE_INPUT: if (mi->flags & MenuButtonDisabled) { break; } @@ -1351,6 +1510,23 @@ global int MenuKey(int key) // FIXME: Should be MenuKeyDown(), and act on _new_ case 'Q': Exit(0); default: + mi = menu->items; + i = menu->nitems; + while (i--) { + switch (mi->mitype) { + case MI_TYPE_INPUT: + if (!(mi->flags & MenuButtonDisabled)) { + menu->items[MenuButtonCurSel].flags &= ~MenuButtonSelected; + mi->flags |= MenuButtonSelected; + MenuButtonCurSel = mi - menu->items; + MustRedraw |= RedrawMenu; + goto inkey; + } + default: + break; + } + mi++; + } DebugLevel3("Key %d\n",key); return 0; } @@ -1390,6 +1566,19 @@ global void MenuHandleMouseMove(int x,int y) continue; } break; + case MI_TYPE_INPUT: + xs = menu->x + mi->xofs; + ys = menu->y + mi->yofs; + if (x<xs || x>xs + mi->d.input.xsize || y<ys || y>ys + mi->d.input.ysize) { + if (!(mi->flags&MenuButtonClicked)) { + if (mi->flags&MenuButtonActive) { + RedrawFlag = 1; + mi->flags &= ~MenuButtonActive; + } + } + continue; + } + break; case MI_TYPE_PULLDOWN: xs = menu->x + mi->xofs; if (mi->flags&MenuButtonClicked) { @@ -1480,6 +1669,7 @@ global void MenuHandleMouseMove(int x,int y) case MI_TYPE_PULLDOWN: case MI_TYPE_LISTBOX: case MI_TYPE_VSLIDER: + case MI_TYPE_INPUT: if (!(mi->flags&MenuButtonActive)) { RedrawFlag = 1; mi->flags |= MenuButtonActive; @@ -1515,6 +1705,7 @@ global void MenuHandleButtonDown(int b) case MI_TYPE_PULLDOWN: case MI_TYPE_LISTBOX: case MI_TYPE_VSLIDER: + case MI_TYPE_INPUT: if (MenuButtonCurSel != -1) { menu->items[MenuButtonCurSel].flags &= ~MenuButtonSelected; } @@ -1668,6 +1859,7 @@ global void ProcessMenu(int MenuId, int Loop) case MI_TYPE_PULLDOWN: case MI_TYPE_LISTBOX: case MI_TYPE_VSLIDER: + case MI_TYPE_INPUT: mi->flags &= ~(MenuButtonClicked|MenuButtonActive|MenuButtonSelected); // FIXME: Maybe activate if mouse-pointer is over it right now? if (i == menu->defsel) {