forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

A nudge in the right direction, please [crappy menu system]

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS2 Development
View previous topic :: View next topic  
Author Message
LBGSHI



Joined: 07 Aug 2006
Posts: 136

PostPosted: Sat Jan 17, 2009 3:31 pm    Post subject: A nudge in the right direction, please [crappy menu system] Reply with quote

This is primarily for testing, and so I can toy around with a skeleton menu system, before I improve all the inefficient functions and redundancies, and remake this almost entirely from scratch again. However, I still really need to know what the hell is going wrong here, heh. Here is the source to skeleton.c, a simple menu system:

Code:

/*skeleton.c

Very badly designed skeleton GUI for Artemis (raw, hacky, scr_printf text on a black background, and
   screen transitions via init_scr(). Just something to get the ball rolling.) Borrowed
   scandalously (heh) from Pukko's padlib - many thanks to him for providing it, and for everyone else's
   work in improving it. Enjoy, and please - make something better!
   
               - Lazy Bastard
                                                            */
            

#include <tamtypes.h>
#include <kernel.h>
#include <sifrpc.h>
#include <loadfile.h>
#include <stdio.h>
#include <debug.h>

#include "libpad.h"

#define ROM_PADMAN

#if defined(ROM_PADMAN) && defined(NEW_PADMAN)
#error Only one of ROM_PADMAN & NEW_PADMAN should be defined!
#endif

#if !defined(ROM_PADMAN) && !defined(NEW_PADMAN)
#error ROM_PADMAN or NEW_PADMAN must be defined!
#endif

static char padBuf[256] __attribute__((aligned(64)));

static char actAlign[6];
static int actuators;


int menuNumber;

void mainMenuS() {
   init_scr();

    scr_printf("\n\n\n\n\n          Project Artemis\n\n"
               "          Welcome to the Project Artemis (terrible) skeleton GUI.\n\n\n\n"
               "         *Start Game\n\n"
               "          Options\n\n");
               menuNumber = 1;
         }
         
void mainMenuO() {
   init_scr();

    scr_printf("\n\n\n\n\n          Project Artemis\n\n"
               "          Welcome to the Project Artemis (terrible) skeleton GUI.\n\n\n\n"
               "          Start Game\n\n"
               "         *Options\n\n");
                menuNumber = 2;
         }

void startMenu1() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Start menu.\n\n\n\n"
            "         *Choice 1\n\n"
            "          Choice 2\n\n"
            "          Choice 3\n\n");
            menuNumber = 3;      
         }   
         
void startMenu2() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Start menu.\n\n\n\n"
            "          Choice 1\n\n"
            "         *Choice 2\n\n"
            "          Choice 3\n\n");
            menuNumber = 4;
         }
         
void startMenu3() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Start menu.\n\n\n\n"
            "          Choice 1\n\n"
            "          Choice 2\n\n"
            "         *Choice 3\n\n");
            menuNumber = 5;
         }
         
void optionsMenu1() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Options menu.\n\n\n\n"
            "         *Choice 1\n\n"
            "          Choice 2\n\n"
            "          Choice 3\n\n");
            menuNumber = 6;
         }
         
void optionsMenu2() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Options menu.\n\n\n\n"
            "          Choice 1\n\n"
            "         *Choice 2\n\n"
            "          Choice 3\n\n");
            menuNumber = 7;
         }
         
void optionsMenu3() {
   init_scr();
   scr_printf("\n\n\n\n\n          Welcome to the (terrible) Options menu.\n\n\n\n"
            "          Choice 1\n\n"
            "          Choice 2\n\n"
            "         *Choice 3\n\n");
            menuNumber = 8;
         }
         
         


/*
 * Local functions
 */

/*
 * loadModules()
 */
void
loadModules(void)
{
    int ret;

   
#ifdef ROM_PADMAN
    ret = SifLoadModule("rom0:SIO2MAN", 0, NULL);
#else
    ret = SifLoadModule("rom0:XSIO2MAN", 0, NULL);
#endif
    if (ret < 0) {

        SleepThread();
    }   

#ifdef ROM_PADMAN
    ret = SifLoadModule("rom0:PADMAN", 0, NULL);
#else
    ret = SifLoadModule("rom0:XPADMAN", 0, NULL);
#endif
    if (ret < 0) {
 
        SleepThread();
    }
}

/*
 * waitPadReady()
 */
int waitPadReady(int port, int slot)
{
    int state;
    int lastState;
    char stateString[16];

    state = padGetState(port, slot);
    lastState = -1;
    while((state != PAD_STATE_STABLE) && (state != PAD_STATE_FINDCTP1)) {
        if (state != lastState) {
            padStateInt2String(state, stateString);
   
                 
        }
        lastState = state;
        state=padGetState(port, slot);
    }
    // Was the pad ever 'out of sync'?
    if (lastState != -1) {
     
    }
    return 0;
}


/*
 * initializePad()
 */
int
initializePad(int port, int slot)
{

    int ret;
    int modes;
    int i;

    waitPadReady(port, slot);

    // How many different modes can this device operate in?
    // i.e. get # entrys in the modetable
    modes = padInfoMode(port, slot, PAD_MODETABLE, -1);
   

    if (modes > 0) {
     
        for (i = 0; i < modes; i++) {
           
        }
       
    }

 

    // If modes == 0, this is not a Dual shock controller
    // (it has no actuator engines)
    if (modes == 0) {
      
        return 1;
    }

    // Verify that the controller has a DUAL SHOCK mode
    i = 0;
    do {
        if (padInfoMode(port, slot, PAD_MODETABLE, i) == PAD_TYPE_DUALSHOCK)
            break;
        i++;
    } while (i < modes);
    if (i >= modes) {
       
        return 1;
    }

    // If ExId != 0x0 => This controller has actuator engines
    // This check should always pass if the Dual Shock test above passed
    ret = padInfoMode(port, slot, PAD_MODECUREXID, 0);
    if (ret == 0) {
       
        return 1;
    }

 

    // When using MMODE_LOCK, user cant change mode with Select button
    padSetMainMode(port, slot, PAD_MMODE_DUALSHOCK, PAD_MMODE_LOCK);

    waitPadReady(port, slot);
 

    actuators = padInfoAct(port, slot, -1, 0);
 

    if (actuators != 0) {
        actAlign[0] = 0;   // Enable small engine
        actAlign[1] = 1;   // Enable big engine
        actAlign[2] = 0xff;
        actAlign[3] = 0xff;
        actAlign[4] = 0xff;
        actAlign[5] = 0xff;

        waitPadReady(port, slot);
       
    }
    else {
       
    }

    waitPadReady(port, slot);

    return 1;
}





int
main()
{
    int ret;
    int port, slot;
    int i;
    struct padButtonStatus buttons;
    u32 paddata;
    u32 old_pad = 0;
    u32 new_pad;


    SifInitRpc(0);
   
    mainMenuS(); /*Load main menu text*/
   


    loadModules();

    padInit(0);



    port = 0; // 0 -> Connector 1, 1 -> Connector 2
    slot = 0; // Always zero if not using multitap

   

   
    if((ret = padPortOpen(port, slot, padBuf)) == 0) {
       
        SleepThread();
    }
   
    if(!initializePad(port, slot)) {

            SleepThread();
    }
   
    for (;;) {                /*Infinite loop to detect pad state*/
           
        i=0;
        ret=padGetState(port, slot);
        while((ret != PAD_STATE_STABLE) && (ret != PAD_STATE_FINDCTP1)) {
            if(ret==PAD_STATE_DISCONN) {

                           }
            ret=padGetState(port, slot);
        }
        if(i==1) {
        }
           
        ret = padRead(port, slot, &buttons); // port, slot, buttons
           
        if (ret != 0) {
            paddata = 0xffff ^ buttons.btns;
               
            new_pad = paddata & ~old_pad;
            old_pad = paddata;
               
           
           
           
            // Directions
            if(new_pad & PAD_LEFT) {
            }
           
            if(new_pad & PAD_RIGHT) {
            }           
           
            if((new_pad & PAD_UP) && (menuNumber == 2)) {
               mainMenuS();
      
            }
                       
            if((new_pad & PAD_UP) && (menuNumber == 4)) {
               startMenu1();
              
            }
           
            if((new_pad & PAD_UP) && (menuNumber == 5)) {
               startMenu2();
              
              
              
              
            }
                       
            if((new_pad & PAD_UP) && (menuNumber == 7)) {
               optionsMenu1();   
              
              
              
                      
            }
           
            if((new_pad & PAD_UP) && (menuNumber == 8)) {
               optionsMenu2();
              
              
              
              
            }
                       
            if((new_pad & PAD_DOWN) && (menuNumber == 1)) {
               mainMenuO();
              
              
              
              
            }
                       
            if((new_pad & PAD_DOWN) && (menuNumber == 3)) {
               startMenu2();
              
              
              
              
            }
           
            if((new_pad & PAD_DOWN) && (menuNumber == 4)) {
               startMenu3();
              
              
              
              
            }
                       
            if((new_pad & PAD_DOWN) && (menuNumber == 6)) {
               optionsMenu2();
              
              
              
              
            }
           
            if((new_pad & PAD_DOWN) && (menuNumber == 7)) {
               optionsMenu3();
              
              
              
              
            }
                       
            if(new_pad & PAD_START) {
            }
           
            if(new_pad & PAD_R3) {
            }
           
            if(new_pad & PAD_L3) {
            }
           
            if(new_pad & PAD_SELECT) {
            }
           
            if(new_pad & PAD_SQUARE) {
            }           
           
            if((new_pad & PAD_CROSS) && (menuNumber == 1)) {
               startMenu1();
               
              
              
              
            }
           
            if((new_pad & PAD_CROSS) && (menuNumber == 2)) {
               optionsMenu1();
               
              
              
              
            }           
           
            if(new_pad & PAD_CIRCLE) {
               
            }
           
            if((new_pad & PAD_TRIANGLE) && (menuNumber > 2)) {
               mainMenuS();
               
              
              
              
            }
           
            if(new_pad & PAD_R1) {
            }
           
            if(new_pad & PAD_L1) {
            }
           
            if(new_pad & PAD_R2) {
            }
           
            if(new_pad & PAD_L2) {
            }
           
       

            // Test the press mode
            /* Calling SetActAlign repetedly will kill the iop :P
             * (guess the EE is too fast for IOP to handle..)
             * So I'd recommend to change the actuator values only once per
             * vblank or so..
             */
            if(buttons.triangle_p) {
#if 0
                actAlign[1] = (i >> 3); buttons.triangle_p;  // Big engine
                padSetActDirect(port, slot, actAlign);
#else
#endif
            }
            // Start little engine if we move right analog stick right
            if(buttons.rjoy_h > 0xf0)
            {
                // Stupid check to see if engine is already running,
                // just to prevent overloading the IOP with requests
                if (actAlign[0] == 0) {
                    actAlign[0] = 1;
                    padSetActDirect(port, slot, actAlign);
                }
               
             
               
            }
        }
    }

    SleepThread();

    return 0;
}


It compiles fine, runs, and everything works fine, except that, when there are three items, and a top item is selected, and DOWN is pressed, the middle item is skipped over, and the bottom item is selected. The strange thing is that this does not occur when a bottom item is selected, and there are three items, and the UP button is pressed. No, that works just as planned, selecting the middle item, after which another UP press will select the top item.

Could someone please point out where I've erred, if that's obvious? I'm guessing it's just some simple lack of proper logic...
_________________
I may be lazy, but I can...zzzZZZzzzZZZzzz...
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
ps2devman



Joined: 09 Oct 2006
Posts: 265

PostPosted: Sat Jan 17, 2009 6:14 pm    Post subject: Reply with quote

Pads are tricky on the PS2...

Too lazy to study/debug your method, but here is a last resort sample, if you need to compare with a working small menu (method nearly identical to the one used in SMS, if I remember correctly, since I learn most of PS2 stuff by studying SMS source) :

http://home.tele2.fr/~fr-51785/ps2_pong.zip
Back to top
View user's profile Send private message
Lukasz



Joined: 19 Jan 2004
Posts: 248
Location: Denmark

PostPosted: Sat Jan 17, 2009 8:39 pm    Post subject: Reply with quote

I think your problem could be related to the fact that your source probably will read the pads more than once pr. frame. Padlib works in such a way that it only updates the pad status after a vsync (new frame), so if you don't wait until the next frame to read the pad status, you might be reading the same status twice or more. This would explain why the results you are getting are inconsistent.

The two pad samples I wrote (for padx and mtap) both wait for vsync before reading the pad status, you might want to check them out.

http://svn.ps2dev.org/filedetails.php?repname=ps2&path=%2Ftrunk%2Fps2sdk%2Fee%2Frpc%2Fpadx%2Fsamples%2Fpadx.c&rev=0&sc=0
http://svn.ps2dev.org/filedetails.php?repname=ps2&path=%2Ftrunk%2Fps2sdk%2Fee%2Frpc%2Fmultitap%2Fsamples%2Fmtap_sample.c&rev=0&sc=0
_________________
Lukasz.dk
Back to top
View user's profile Send private message Visit poster's website
LBGSHI



Joined: 07 Aug 2006
Posts: 136

PostPosted: Mon Jan 19, 2009 5:51 pm    Post subject: Reply with quote

Surprisingly, the same thing happened with your example. I'll do some more work tomorrow, and see if I can figure out what's going on here.
_________________
I may be lazy, but I can...zzzZZZzzzZZZzzz...
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
LBGSHI



Joined: 07 Aug 2006
Posts: 136

PostPosted: Wed Jan 21, 2009 11:22 am    Post subject: Reply with quote

One of the things my mind half-heartedly concocted as a solution worked: I added a continue to each of the if statements controlling menu flow, and the problem is now gone :)
_________________
I may be lazy, but I can...zzzZZZzzzZZZzzz...
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PS2 Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group