* * Simple joystick menu/gui system * * Uses ZP pointer $fc-$ff * * s. judd * 12/30/05 * rel put 'core.ext.s' MAXJOYITEMS EQU 16 * * Menu Item types: * 0 - empty (text only) * 1 - number (min..max) * 2 - list (item, enumeration) * 3 - input * JOYEMPTYITEM equ 0 JOYNUMITEM equ 1 JOYLISTITEM equ 2 JOYINPUTITEM equ 3 deftype JoyMenu uint .labelptr(MAXJOYITEMS) ubyte .type(MAXJOYITEMS) uint .varptr(MAXJOYITEMS) uint .listptr(MAXJOYITEMS) ubyte .listsize(MAXJOYITEMS) ubyte .min(MAXJOYITEMS) ubyte .max(MAXJOYITEMS) uint .firecallback(MAXJOYITEMS) uint .lrcallback(MAXJOYITEMS) ubyte .row(MAXJOYITEMS) ubyte .col(MAXJOYITEMS) ubyte .width(MAXJOYITEMS) ubyte .numchars(MAXJOYITEMS);number of chars printed to screen defend type JoyMenu NewJoyMenu ubyte JoyMenuLength ubyte JoyMenuRow ubyte JoyMenuCol ubyte JoyMenuWidth ubyte JoyCurItem ubyte JoyOrientation *ubyte JoyMenuID *------------------------------- * * Test code * *------------------------------- do 0 ubyte testlist(10,16) = [ & ['Fender'] & ['Gibson'] & ['Carvin'] & ['PRS '] & ] ubyte testvars(10) = [1 2 3 14 5 16 7 18 9 10] ubyte testinput(16) = ['hola'] ubyte count NewMenu(1, 5, 2, 8, 1) AddMenuItem(#'Numtest', JOYNUMITEM, #testvars(0)) SetMinMax(0,17) AddMenuItem(#'Axe', JOYLISTITEM, #testvars(1)) SetEnumList(#testlist, 16) SetMinMax(0,3) SetFireCallback(#testback) AddMenuItem(#'Name', JOYINPUTITEM, #testinput) SetMenuRowCol(5,18) SetMinMax(0,13) AddMenuItem(#'number2', JOYNUMITEM, #testvars(4)) SetMinMax(12,19) testvars(4)=13 AddMenuItem(#' ', JOYEMPTYITEM, #' ') DisplayMenu() repeat count=0 while count<8 wait $d012,255 wait $d012,0 inc count endwhile RunMenu() forever waitchar done sub testback() sprint(0,0) "bang!" endsub fin * * Create new menu * sub ent NewMenu(ubyte newid, ubyte row, ubyte col, ubyte width, ubyte hv)_byte id id = newid * JoyMenuID = newid JoyMenuLength = 0 JoyMenuRow = row JoyMenuCol = col JoyMenuWidth = width JoyOrientation = hv ;0/1 JoyCurItem = 0 endsub * * Add menu item * sub ent AddMenuItem(uint label, ubyte type, uint variable) ubyte k k = JoyMenuLength NewJoyMenu.labelptr(k) = label NewJoyMenu.type(k) = type NewJoyMenu.varptr(k) = variable NewJoyMenu.row(k) = JoyMenuRow NewJoyMenu.col(k) = JoyMenuCol NewJoyMenu.width(k) = JoyMenuWidth NewJoyMenu.firecallback(k) = 0 NewJoyMenu.lrcallback(k) = 0 UpdateRowCol() inc JoyMenuLength JoyCurItem = JoyMenuLength-1 endsub sub UpdateRowCol() if+ JoyOrientation inc JoyMenuRow else JoyMenuCol = JoyMenuCol + (JoyMenuWidth << 1) endif endsub * * Get/Set current item * sub ent GetCurrentItem()_ubyte curitem curitem = JoyCurItem endsub sub ent SetCurrentItem(ubyte curitem) JoyCurItem = curitem endsub * * Reset row/col * sub ent SetMenuRowCol(ubyte row, ubyte col) NewJoyMenu.row(JoyCurItem)=row NewJoyMenu.col(JoyCurItem)=col JoyMenuRow = row JoyMenuCol = col UpdateRowCol() endsub * * Setup enumerated list * sub ent SetEnumList(uint list, ubyte dimsize) ubyte k k = JoyCurItem NewJoyMenu.listptr(k) = list NewJoyMenu.listsize(k) = dimsize NewJoyMenu.min(k) = 0 endsub * * Setup number min/max * sub ent SetMinMax(ubyte min, ubyte max) ubyte k k = JoyCurItem NewJoyMenu.min(k) = min NewJoyMenu.max(k) = max endsub * * Set callback routine (fire button) * sub ent SetFireCallback(uint addr) NewJoyMenu.firecallback(JoyCurItem) = addr endsub sub ent SetLRCallback(uint addr) NewJoyMenu.lrcallback(JoyCurItem) = addr endsub * * Display menu * sub ent DisplayMenu() ubyte k for k=0:JoyMenuLength-1 PrintMenuItem(k) next HighlightItem() endsub * * Print single item * sub PrintMenuItem(ubyte k) ubyte j,temp ubyte row,col,col2 ubyte jtype ubyte str(32) row = NewJoyMenu.row(k) col = NewJoyMenu.col(k) col2 = col + JoyMenuWidth jtype = NewJoyMenu.type(k) CopyString(NewJoyMenu.labelptr(k), #str) sprint(row,col) str$ if+ (jtype = JOYNUMITEM) temp = GetMenuValue(k)_val JoyPrintNum(temp, row, col2) NewJoyMenu.numchars(k)=2 elsif+ (jtype = JOYLISTITEM) JoyPrintList(k, row, col2) NewJoyMenu.numchars(k) = JoyPrintList_numchars elsif+ (jtype = JOYINPUTITEM) JoyPrintInput(k, row, col2) NewJoyMenu.numchars(k) = JoyPrintInput_numchars else NewJoyMenu.numchars(k) = 0 endif endsub * * Cheese num2str * sub JoyPrintNum(ubyte temp, ubyte row, ubyte col) * ubyte screen(25,40)@$0400 ubyte j ubyte num(4) j = 0 if+ (temp>=100) ;cheese num2str num$ = '000' j=2 elsif+ temp>=10 num$ = '00 ' j=1 else num$ = '0 ' j=0 endif while+ (temp>=100) num(0) = num(0)+1 temp=temp-100 endwhile+ while+ (temp>=10) num(j-1) = num(j-1)+1 temp=temp-10 endwhile+ while+ (temp>=1) num(j) = num(j)+1 temp=temp-1 endwhile+ * screen$(row,col) = num$(0:2) sprint(row,col) num$ endsub * * Print the current list item * sub JoyPrintList(ubyte k, ubyte row, ubyte col)_ubyte numchars * ubyte screen(25,40)@$0400 ubyte temp,j,size ubyte str(32) uint zp@$fc temp = GetMenuValue(k)_val size = NewJoyMenu.listsize(k) zp = NewJoyMenu.listptr(k) j = 0 while+ j 0 dec JoyCurItem endif HighlightItem() case+ temp bitand 2 ;down HighlightItem() if+ JoyCurItem < JoyMenuLength-1 inc JoyCurItem endif HighlightItem() case+ temp bitand 4 ;left EraseItem() JoyLeft() PrintMenuItem(JoyCurItem) HighlightItem() CallCallback(NewJoyMenu.lrcallback(JoyCurItem)) case+ temp bitand 8 ;right EraseItem() JoyRight() PrintMenuItem(JoyCurItem) HighlightItem() CallCallback(NewJoyMenu.lrcallback(JoyCurItem)) case+ temp bitand 16 ;fire CallCallback(NewJoyMenu.firecallback(JoyCurItem)) case! temp bitand 16 endtest endsub sub JoyLeft() ubyte temp ubyte jtype ubyte k k = JoyCurItem jtype = NewJoyMenu.type(k) if+ (jtype = JOYNUMITEM) or (jtype = JOYLISTITEM) temp = GetMenuValue(k)_val if+ temp>NewJoyMenu.min(k) SetMenuValue(k, temp-1) endif endif endsub sub JoyRight() ubyte temp ubyte jtype ubyte k ubyte row,col ubyte str(32) k = JoyCurItem jtype = NewJoyMenu.type(k) if+ (jtype = JOYNUMITEM) or (jtype = JOYLISTITEM) temp = GetMenuValue(k)_val if+ temp