menu.z80 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. menuMem = saveSScreen
  2. ;Now define where vars are located, 17 bytes required in all.
  3. textbox_top = menuMem
  4. textbox_left = textbox_top+1 ;needs to follow textbox_top
  5. textbox_bottom = menuMem+2
  6. textbox_width = textbox_bottom
  7. textbox_right = textbox_bottom+1 ;needs to follow textbox_bottom
  8. menucallptr = menuMem+4
  9. menutop = menuMem+6
  10. menucur = menuMem+8
  11. menuselection = menuMem+10
  12. menuheader_ptr = menuMem+12
  13. menuheader_coord= menuMem+14
  14. menuheader_cur = menuMem+16 ;1 byte
  15. menu_num_items = menuMem+17 ;2 bytes
  16. menu_get = menuMem+19
  17. menu_sel = menuMem+21
  18. menu_temp = menuMem+23
  19. menuopts = menuMem+25
  20. menudefault = TempWord1
  21. menutopinit = TempWord4
  22. #define MENU_MAX_ELEMENTS ((menuMem+768-menuopts)>>1)
  23. ;Menu:
  24. ;Get the y coordinate
  25. ld hl,(parsePtr)
  26. ld a,(hl)
  27. cp $AE
  28. jp z,fancymenu
  29. call p1_ParseFullArg
  30. push bc
  31. ;Get the x coordinate
  32. call p1_ParseNextFullArg
  33. pop hl
  34. ld h,c
  35. ;Save the coords
  36. ld (textbox_top),hl
  37. ; Get the width of the menu
  38. call p1_ParseNextFullArg
  39. ld (textbox_width),bc
  40. ;Get the header
  41. call p1_ParseNextFullArg
  42. ld (menuheader_ptr),bc
  43. ld hl,menuopts
  44. ld bc,0
  45. menu_param_loop:
  46. inc bc
  47. ld a,b
  48. cp MENU_MAX_ELEMENTS>>8
  49. jr nz,+_
  50. ld a,c
  51. cp MENU_MAX_ELEMENTS&255
  52. jp menu_err
  53. _:
  54. push bc
  55. push hl
  56. ld hl,(parsePtr)
  57. inc hl
  58. ld a,(hl)
  59. cp $AE
  60. jr z,menu_select_default
  61. call p1_ParseNextFullArg
  62. pop hl
  63. ld (hl),c
  64. inc hl
  65. ld (hl),b
  66. inc hl
  67. pop bc
  68. cp $2B
  69. jr z,menu_param_loop
  70. _:
  71. ld de,0
  72. jr +_
  73. menu_select_default:
  74. pop hl
  75. call p1_ParseNextFullArg
  76. ld h,b
  77. ld l,c
  78. dec hl
  79. pop bc
  80. dec bc
  81. ;If hl is negative, set DE to 0
  82. ld a,h
  83. add a,a
  84. jr c,-_
  85. ;set DE to min(HL,BC)
  86. ld d,b
  87. ld e,c
  88. dec de
  89. sbc hl,de
  90. jr nc,+_
  91. add hl,de
  92. ex de,hl
  93. _:
  94. ld (menudefault),de
  95. ;Save the number of elements
  96. ld (menu_num_items),bc
  97. push bc
  98. call p1_chardim
  99. ld a,c
  100. ld (font_height),a
  101. pop bc
  102. ld l,a
  103. ;Now we need to render the menu, but first we'll get the height of the menu in pixels
  104. ;4+font_height*min(9-int(y/font_height),BC+1
  105. ;60/font_height-1 is the initial E value
  106. ld a,59
  107. ld e,-1
  108. inc e
  109. sub l
  110. jr nc,$-2
  111. ld a,(textbox_top)
  112. add a,a
  113. jr c,cmp_menu_height
  114. sla l
  115. .db $FE
  116. _:
  117. dec e
  118. sub l
  119. jr nc,-_
  120. cmp_menu_height:
  121. ;E is the max height
  122. ;if BC+1 is smaller, use that
  123. inc bc
  124. inc b
  125. dec b
  126. jr nz,+_
  127. ld a,c
  128. cp e
  129. jr nc,+_
  130. ld e,c
  131. _:
  132. ;Now E is the number of items shown
  133. ;if menudefault>=E, then need to set menutopinit to menudefault-E+1
  134. ld hl,(menudefault)
  135. inc h
  136. dec h
  137. jr nz,$+6
  138. ld a,l
  139. sub e
  140. jr c,+_
  141. ld l,a
  142. jr nc,$+3
  143. inc h
  144. inc hl
  145. jr $+5
  146. _:
  147. ld hl,0
  148. ld (menutopinit),hl
  149. ;now do E*FONT_HEIGHT+4, given that it won't overflow 8 bits
  150. ld a,(font_height)
  151. ld b,a
  152. ld a,5
  153. _:
  154. add a,e
  155. djnz -_
  156. ;now set the width and height
  157. ld e,a
  158. ld a,(textbox_width)
  159. ld d,a
  160. ld ix,menu_command_lookup
  161. menu_entry:
  162. ;Set the default graphics buffer
  163. ; ld hl,(BufPtr)
  164. ; ld (gbuf_temp),hl
  165. ;save and set the the font method
  166. ld a,(textmode)
  167. or a
  168. push af
  169. ld hl,(FontPointer)
  170. push hl
  171. jr nz,+_
  172. ld a,2
  173. ld (textmode),a
  174. ld hl,FontSet
  175. ld (FontPointer),hl
  176. xor a
  177. ld (font_ptr_page),a
  178. _:
  179. ld bc,(textbox_top)
  180. ld hl,(menuheader_ptr)
  181. call menuroutine
  182. pop hl
  183. ld (FontPointer),hl
  184. xor a
  185. ld (font_ptr_page),a
  186. pop af
  187. ld (textmode),a
  188. ret
  189. fancymenu:
  190. ;header,y,x,h,w,get,sel
  191. call p1_ParseNextFullArg
  192. ld (menuheader_ptr),bc
  193. call p1_ParseNextFullArg
  194. push bc
  195. call p1_ParseNextFullArg
  196. pop hl
  197. ld h,c
  198. ld (textbox_top),hl
  199. call p1_ParseNextFullArg
  200. push bc
  201. call p1_ParseNextFullArg
  202. pop hl
  203. ld h,c
  204. push hl ;w,h
  205. call p1_ParseNextFullArg
  206. ld (menu_get),bc
  207. call p1_ParseNextFullArg
  208. ld (menu_sel),bc
  209. call p1_chardim
  210. ld a,c
  211. ld (font_height),a
  212. ld hl,0
  213. ld (menutopinit),hl
  214. ld (menudefault),hl
  215. pop de
  216. ld ix,fancymenu_lookup
  217. jr menu_entry
  218. menu_err:
  219. ld hl,ErrStackOverflow_push
  220. ld (prev_page_call),hl
  221. jp prev_page_call
  222. fancymenu_lookup:
  223. ;save the current parsePtr
  224. ld hl,(parsePtr)
  225. push hl
  226. ;save Ans and replace with the current cursor
  227. ld hl,(Ans)
  228. push hl
  229. ;save thetaprime
  230. ld hl,(ThetaPrimeVar)
  231. push hl
  232. ;Save the text coordinates
  233. ld hl,(TextRow)
  234. push hl
  235. ;Set ThetaPrime
  236. ld l,a
  237. ld h,0
  238. ld (ThetaPrimeVar),hl
  239. ;now set the location to start parsing at
  240. ld hl,(menu_get)
  241. jr nc,+_
  242. ld hl,(menu_sel)
  243. ld bc,(menucur)
  244. _:
  245. ld (parsePtr),hl
  246. ;set Ans
  247. ld (Ans),bc
  248. ;Now parse
  249. call p1_ParserNext
  250. ;Restore text coordinates
  251. pop hl
  252. ld (TextRow),hl
  253. ;restore thetaprimevar
  254. pop hl
  255. ld (ThetaPrimeVar),hl
  256. ;restore Ans
  257. pop hl
  258. ld (Ans),hl
  259. ;restore parsePtr
  260. pop hl
  261. ld (parsePtr),hl
  262. ;return 0 if failed
  263. ld h,b
  264. ld l,c
  265. ld a,b
  266. or c
  267. ret nz
  268. scf
  269. ret
  270. menu_command_lookup:
  271. jr c,menu_command_select
  272. ;get element number BC
  273. ld hl,(menu_num_items)
  274. scf
  275. sbc hl,bc
  276. ret c
  277. ld hl,menuopts
  278. add hl,bc
  279. add hl,bc
  280. ld a,(hl)
  281. inc hl
  282. ld h,(hl)
  283. ld l,a
  284. ret
  285. menu_command_select:
  286. ld bc,(menucur)
  287. inc bc
  288. ret