Thread: dos menu....

  1. #1
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67

    dos menu....

    hi, drake here, and I have been making a dos "animated" menu that someone could browse through. The only thing I don't get is how I would "Go Back" to the previous menu. For example, if I was in options in Halo(just an example, I'm not making an amazing menu, this is just for learning puposes) and I press the B button, I go back to the previous menu. Here I have some code and I want to use the number 5 in the difficulty menu to go back and the 'n' character in the quit menu to go back. I believe it has to do w/ do loops but I don't really understand them so please assist in any way possible. Thanks.


    failed attempt of do loop in code
    Code:
        
        cout <<"\n\n\n\n            PRESS ENTER";
        cin.ignore(std::cin.rdbuf()->in_avail()+1);
        system("cls");
        do
        {
            int menu;
            cout<<"G O T Y"<<endl;
            cout<<"\n\n\n";
            cout<<"'~-MENU-~'\n"<<endl;
            cout<<"1 - Start"<<endl;
            cout<<"2 - Quit"<<endl;
            cout<<"Input: ";
            cin>>menu;
        
                switch(menu)
                    {
                    case 1:
                        int difficulty;
                        std::cout<<"Dfficulty Levels"<<std::endl;
                        std::cout<<"1 - Easy"<<std::endl;
                        std::cout<<"2 - Normal"<<std::endl;
                        std::cout<<"3 - Heroic"<<std::endl;
                        std::cout<<"4 - Legendary"<<std::endl;
                        std::cout<<"5<-GO BACK"<<std::endl;
                        cin>>difficulty;
                        
                        if(difficulty == 1)
                        {
                             cout<<"You picked Easy"<<endl;
                             system("pause");
                        }
                        
                        if(difficulty == 2)
                        {
                             std::cout<<"You picked Normal"<<std::endl;
                             system("pause");
                        }
                        
                        if(difficulty == 3)
                        {
                            std::cout<<"You picked Heroic"<<std::endl;
                            system("pause");
                        }
                        
                        if(difficulty == 4)
                        {
                            std::cout<<"You picked Legendary"<<std::endl;
                            system("pause");
                        }
            case 2:
                      int quit;
                      cout<<"quit? (y/n): ";
                      cin>>quit;
                    
                      if(quit == 'y')
                      {
                         system("cls");
                         cout<<"Thank's for playing GOTY!\n\n\nGOODBYE";
                      }
                    }
        }while(difficulty == 5 || quit == 'n')
    I have the animation part before all this code you see here, I didn't wanna take up a hole page(pretty much alot of system("cls").

    .

  2. #2
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67

    Exclamation

    i would also like to know how to make it so in my little animation at the beginning, I can press Enter at any time to skip the intro. My intro uses for loops. I'm not sure if i could use an if statement or not and hold the for loop as long as the user dosn't hit enter...

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    here is a sample of a menu i'm doing
    Code:
    bool ValidInput, MenuQuit;
    
    do
    {
    	MenuQuit = false;
    	ValidInput = true;
    	/*
    	clear the screen
    	output main menu
    	*/
    	do
    	{
    		switch(getInputFunc())
    		{
    		case '1':
    			//menu1
    			do
    			{
    				MenuQuit = false;
    				ValidInput = true;
    
    				/*
    				clear the screen
    				output menu1 here
    				*/
    				do
    				{
    					switch(getInputFunc())
    					{
    					case '1':
    						//menu 1 submenu 1
    						//do stuff for option 1 of submenu 1
    						break;
    					case '2':
    						//menu 1 submenu 2
    						//do stuff for option 2 of submenu 1
    						break;
    					case 'Q':
    						//go back
    						MenuQuit = true;
    						break;
    					default: //1 2 or Q was not press
    						ValidInput = false;
    					}
    				}
    				while(!ValidInput); //loops input until 1 2 or Q is pressed
    			}
    			while(!MenuQuit);//loops submenu 1 until Q is pressed
    			break;
    		case '2':
    			//2nd option
    			//similar to menu 1 etc etc
    			break;
    		case 'Q':
    			//quitgame
    			MenuQuit = true;
    			break;
    		default:  //1 2 or Q was not press
    			ValidInput = false;
    		}
    	}
    	while(!ValidInput); //loops until case statement executes
    }
    while(!MenuQuit);//loops main menu until Q is pressed
    getInputFunc is a loop that gets a single char from the user and returns it. I'm getting input this way because I'm actually using windows console input (so it's actually returning a WORD in my program), but there are many different ways you could get your own input. The entire section of the first case could be put into it's own function, as I believe multiple nested switches can become hard to read. I'm still a beginner, so this might not be a good way.

    edit: getInputFunc is a custom function I made, and it's just there to show that's where I'm getting the input for the switch.
    Last edited by Syneris; 01-08-2006 at 01:27 PM.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code:
    class MenuItem
    {
      char *m_pText;
      int m_iIndex;
      int m_iRow;
      int m_iColumn;
      ....
      public:
        ...
        ...
        SetResponseFunc(Func_ptr *pFunc);
    
    };
    
    class Menu
    {
      std::vector<MenuItem *> vMenuItems;
     
      Menu *m_pNext;
      Menu *m_pPrev;
    
      public:
       ...
       ...
       DrawMenu(void);
       bool SetNext(CMenu *pMenu=NULL);
       bool SetPrev(CMenu *pMenu=NULL);
      
    };
    
    class CMenuSystem
    {
      std::vector<CMenu *> vMenus;
      ...
      ...
    };
    Something like that ought to do the trick.
    Last edited by VirtualAce; 01-08-2006 at 01:34 PM.

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    203
    That looks really good Bubba. I'd really like to ask some questions about it, but don't want to hijack this thread. From the original posters code though, i'm assuming (but you know what happens when you assume) it might be a bit too advanced of a solution for him (and slightly more advanced than where I am in my learning process). Going to bookmark this, learn vectors and function pointers, then take another look at that time. Must games have menus, so having something as reuseable as your code would be a great benefit.

  6. #6
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67
    Quote Originally Posted by Syneris
    it might be a bit too advanced of a solution for him
    that is completely true

    .

  7. #7
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67

    Lightbulb dos menu complete

    thanks for the help guys, but I found a solution to my problem, I used goto commands, but I'm not sure if that was the right choice even though they worked how I wanted them to. If you have any suggestions or comments feel free to post.

  8. #8
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67

    omg

    well, it looks like my program works for the main part but I can't get the correct input for my switch and it throws me either into the default or case 1 of the 2 case switch. The back: is the goto method i use to get around the menu, works nicely for the code. Here is my code, if you have any questions on the functions....
    1. goty() = Just the intro to the game
    2. item() = Displays the main menu, no input cause of frustration
    3. input() = Not displayed after menu cause switch initiates it. Suppose to return an integer of either 1 or 2 for the menu. If you need to see function code, ask.

    Code:
    //Game Menu
    
    #include<iostream>
    #include "item.h"
    #include "goty.h"
    #include "input.h"
    
    using namespace std;
    
    
    int main()
    {
        //INTRO
        goty();
        
        //MAIN MENU
        back:
        item();
    
    
                switch(input())
                {
                    case 1:
                    {
                        system("cls");
                        int difficulty;
                        std::cout<<"Dfficulty Levels"<<std::endl;
                        std::cout<<"1 - Easy"<<std::endl;
                        std::cout<<"2 - Normal"<<std::endl;
                        std::cout<<"3 - Heroic"<<std::endl;
                        std::cout<<"4 - Legendary"<<std::endl;
                        std::cout<<"5<-GO BACK"<<std::endl;
                        cin>>difficulty;
                        
                        if(difficulty == 1)
                        {
                             system("cls");
                             cout<<"You picked Easy\n"<<endl;
                             system("pause");
                        }
                        
                        if(difficulty == 2)
                        {
                             system("cls");
                             std::cout<<"You picked Normal\n"<<std::endl;
                             system("pause");
                        }
                        
                        if(difficulty == 3)
                        {
                            system("cls");
                            std::cout<<"You picked Heroic\n"<<std::endl;
                            system("pause");
                        }
                        
                        if(difficulty == 4)
                        {
                            system("cls");
                            std::cout<<"You picked Legendary\n"<<std::endl;
                            system("pause");
                        }
                        if(difficulty == 5)
                        {
                        system("cls");
                        goto back;
                        }
                        break;
                    }
            case 2:
            {
                      char quit;
                      system("cls");
                      cout<<"quit? (y/n): ";
                      cin>>quit;
                    
                      if(quit == 'y')
                      {
                         system("cls");
                         cout<<"Thank's for playing GOTY!\n\n\nGOODBYE\n\n";
                         system("pause");
                      }
                      if(quit == 'n')
                      {
                      system("cls");
                      goto back;
                      }
                      break;     
            }
             default:
             {
                      system("cls");
                      cout<<"You made an illegal choice\n\n";
                      system("pause");
                      system("cls");
                      goto back;
             }
             break;
                       
            }
    }

  9. #9
    Registered User
    Join Date
    Jan 2006
    Posts
    14
    how didi you use the loops for the dos menu? (to create animation)
    ???

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    That is NOT a good practice to use. We won't start the discussion here, but just don't use goto.

    I'm not sure if I can explain it any better but using the class design I showed you is much more versatile and will work for every menu in your game.

    Stay away from goto's.

    Change your approach to an object oriented design and you will have much more success. So what do you do when you have an in-game menu, re-write all that code again? Doesn't that seem kind of redundant?

    Wouldn't it be easier to do something like this:

    Code:
    CMenu *pMainMenu=new CMenu();
    pMainMenu->SetTitle("Please choose an option",2,ALIGN_HORIZ);
    pMainMenu->AddItem("Start game",ALIGN_HORIZ);
    pMainMenu->AddItem("Load game",ALIGN_HORIZ)
    pMainMenu->AddItem("Options",ALIGN_HORIZ);
    pMainMenu->AddItem("Exit",ALIGN_HORIZ | MENU_EXIT);
    
    CMenu *pMenu=new CMenu();
    pMenu->SetTitle("Select a difficulty",5,ALIGN_HORIZ);
    pMenu->AddItem("Easy",ALIGN_HORIZ);
    pMenu->AddItem("Normal",ALIGN_HORIZ);
    pMenu->AddItem("Hard",ALIGN_HORIZ);
    pMenu->AddItem("Back",ALIGN_HORIZ);
    pMenu->SetPrev("Back",pMainMenu);
    
    pMainMenu->SetNext("Options",pMenu);
    
    int result=pMainMenu->RunMenu();
    This would set the difficulty menu as a sub menu of main menu item 3 or Options. If you select back in Options, it has it's previous menu set as pMainMenu and it would return to that menu.

    Each menu item then can have a CMenu object next and prev associated with it. This is very similar to a Windows menu bar that has submenu's, sub-popups with sub-menus, etc.

    You could use function pointers but with classes you will run into some issues, but it's not impossible. Or you could just respond by returning an integer from RunMenu() which indicates the user's reponse. The SetPrev and SetNext functions would assign prev and next menu's to an item. RunMenu() would understand this and would auto-switch the menu's if the user selected the item specified in these calls.

    Using this you could setup menu's from templates on disk and then run them at any point in your game.

    A couple of objects to handle everything. No re-typing lines and lines of code for every menu you need and everything is encapsulated. Just what you want.

    Based on those functions you should be able to design a CMenu class and a CMenuItem class. CMenu should have:

    Public functions
    void SetTitle(LPCSTR strTitle,int Row,int iAlignMode)
    int AddItem(LPCSTR strName,int iAlignMode);
    void DeleteItem(int index);
    void DeleteItem(CMenuItem *pItem);
    bool InsertItem(LPCSTR strName,int iInsertAfter,int iAlignMode);
    int RunMenu(void);
    bool SetNext(LPCSTR strName,CMenu *pMenu);
    bool SetNext(int iIndex,CMenu *pMenu);
    bool SetNext(CMenuItem *pItem,CMenu *pMenu);
    bool SetPrev(LPCSTR strName,CMenu *pMenu);
    bool SetPrev(int iIndex,CMenu *pMenu);
    bool SetPrev(CMenuItem *pItem,CMenu *pMenu);
    CMenuItem *GetMenuItem(int index);


    Private functions
    void UpdateMenu(void);
    void DisplayMenu(void);
    void GetInput(void);

    I leave the rest to you. But it's a good start I think.
    Last edited by VirtualAce; 01-15-2006 at 02:53 AM.

  11. #11
    lv.42 Berserker Drake's Avatar
    Join Date
    Jun 2005
    Posts
    67
    thnx

    .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-05-2009, 10:25 AM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. Constructive Feed Back (Java Program)
    By xddxogm3 in forum Tech Board
    Replies: 12
    Last Post: 10-10-2004, 03:41 AM
  4. quick question about C Dos text menu pgm i was doing
    By Shadow in forum C Programming
    Replies: 2
    Last Post: 09-16-2001, 10:26 AM