Author Topic: Menus  (Read 3780 times)

0 Members and 1 Guest are viewing this topic.

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Menus
« on: August 31, 2012, 05:24:47 am »
I spent a while last night trying to figure out a simple way to select the closest option beneath the currently selected option in a menu when the x coordinates aren't aligned.

Here's what i came up with:
1. Starting from the saved coordinates of the currently selected option, read the remaining coordinates.
2. If there are coordinates below, compare those coordinates to see which has the closest x value.
3. Compare the x values.

The code (for going down):
Code: [Select]
call checkEOM
ret z

ld a,(numOptions)
dec a
sub (hl)
ld b,a ;(numOptions-1)-curOption = número máximo de coordinadas que buscar

ld a,(hl) ;cur option
add a,a ;x2 por el tamaño de las coordinadas: 2 bytes por cada opción
ld e,a
ld d,0
ld hl,buttonCoords
add hl,de ;añadir offset
ld a,(hl) ;x value of current option
ex af,af' ;guardar coordinada x en a'
inc hl
ld a,(hl) ;y value of current option
w2Down_loop:
inc hl ;saltar valor x de la siguiente opción
inc hl ;valor y
cp (hl) ;compare current y coordinate to the next option until we reach an option on the next line or there are no more entries
jr nz,w2Down_found
djnz w2Down_loop ;repeat until no more entries left
;si no hay más opciones debajo de nosotrxs, simplemente avanzar a la próxima opción
ld hl,curOption
inc (hl)
ret
w2Down_found:
dec hl ;retroceder a la coordinada x
ex af,af' ;a = x value of curOption
sub 4 ;ajustarlo un poco porque las coordinadas son guardadas unos 9 píxeles a la izquierda del texto
jr nc,$+3
xor a
ld b,a ;guardarlo
ld c,$FF ;c = the nearest x value to our current x
;basically repeat until the next value is further away from the current x than the previously checked value.
; since we only check the line below, if one entry starts to get further away, all the rest of the entries on
; that line must also get further away
w2D_f_loop:
ld a,b ;recall x value
sub (hl) ;subtract x value of the new coordinate
jr nc,$+4
neg ;if it's negative, make it positive
cp c ;check if it's closer or further away
jr nc,w2D_update ;if it's further away than the previous coordinate, exit
ld c,a ;otherwise, update c and continue
inc hl
inc hl
jr w2D_f_loop
w2D_update:
ld de,buttonCoords+1
sbc hl,de
ld a,l
rra ;/2
ld (curOption),a
ret

checkEOM:
ld a,(numOptions)
dec a
cp (hl) ;check if numOptions-1 = curOption (ie si quedan más opciones)
ret
I have a list of coordinates for each menu item, (x,y). What i do is check first if we are at the end of the coordinates list, load how many items are left after the currently selected item into b. Then loop until we get to either the first item with a higher y coordinate or reach the end of the list. If we reach the end of the list and we're still at the same y coordinate, just move to the next item. Otherwise, compare the items on that row until they start getting further away from the current x value, and jump to that item.

I think my algorithm is a little bloated, or at least it seems like a lot of code for something that doesn't seem all that complicated.

Offline shmibs

  • しらす丼
  • Administrator
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2132
  • Rating: +281/-3
  • try to be ok, ok?
    • View Profile
    • shmibbles.me
Re: Menus
« Reply #1 on: August 31, 2012, 11:16:47 am »
you could easily just hardcode this. consider the whole thing as a rectangular, 6*4 grid, assign the bottom words to x positions 1 through 3 and 4 through 6, so anything in that range will point to them, and then just make x jump by 3 when it's on the bottom section instead of 1.

EDIT: and, if you have some situations where not all of the menu items will be visible/selectable, just check for that and jump again.
« Last Edit: August 31, 2012, 11:22:40 am by shmibs »

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: Menus
« Reply #2 on: August 31, 2012, 04:21:52 pm »
That's an interesting idea, it just makes writing up the menus a little more of a pain and letting one item span multiple columns would take up about just as much space. And the screen won't always nicely fit into a grid. It's a cool idea, though, thanks.

Here's the data being read, btw:
Code: [Select]
.db T_MENU,_p,_l,_a,_y,_e,_r,_1,T_MENU,_p,_l,_a,_y,_e,_r,_2
.db T_NEWXY,11,10,T_MENU,_1,T_MENU,_2,T_MENU,_3,T_MENU,_4,T_MENU,_5,T_MENU,_6
.db T_NEWXY,0,22,_O,_p,_t,_i,_o,_n,_s,_COLON
.db T_NEWXY,0,30,T_MENU,_b,_u,_y,T_MENU,_s,_o,_m,_e,_t,_h,_i,_n,_g
.db T_NEWXY,14,40,T_MENU,_p,_l,_a,_y,T_MENU,_q,_u,_i,_t
.db T_NEWXY,10,50,T_MENU,_a,_t,_a,_c,_a,_r,T_NEWX,47,T_MENU,_e,_l,_e,_m,_e,_n,_t,_o
.db T_NEWXY,10,56,T_MENU,_h,_a,_b,_i,_l,T_NEWX,47,T_MENU,_f,_u,_g,_a,_r,$FF
(T_MENU is the menu token, T_NEWX/T_NEWXY also do just what it sounds like they should do ;))