menu.z80 5.9 KB

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