UrForth: properly mark scattered colon words
[urasm.git] / libs / winsys / winmenu.zas
blobc53c8b0854e7e034b7a8ae81d18812dbf1d51290
1   module WinMenu
2   ;; requires: WinSys, WinArrow, WinStick, WinMouse, WinInput
4 curMenu:          dw dummyMenu
5 lastSelectedItem: db #ff
7 lastItemSA:  dw 0  ; last inverted item's screen address
8 lastItemWdt: db 0
10 dummyMenu: db #ff
13 __TEST_INTR_TIME__ EQU 0
16 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17 ;; ÉÎ×ÅÒÔÉÒÕÅÍ ÐÕÎËÔ ÍÅÎÀÈÉ
18 ;; in:
19 ;;   hl: pointer to item data (curItemSA, curItemWdt)
20 ;; out:
21 ;;   af', af, bc, de, hl: destroyed
22 InverseMenuBar:
23   ld    e,(hl)
24   ld    a,e
25   ld    (.invLVar),a
26   inc   hl
27   ld    d,(hl)
28   ld    a,d
29   or    a
30   ret   z     ; dummy item
31   inc   hl
32   ld    a,(hl)
33   or    a
34   ret   z
35   ld    c,8  ; height
36 .lineloop:
37   ld    b,a
38   ex    af,af'
39 .invloop:
40   ld    a,(de)
41   cpl
42   ld    (de),a
43   inc   e
44   djnz  .invloop
45   dec   c
46   ret   z
47   ex    af,af'
48   ld    e,0
49 .invLVar: equ $-1
50   inc   d
51   jp    .lineloop
54 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55 ;; calc address for the given item
56 ;; in:
57 ;;  a: item or #ff
58 ;;  hl: pointer to item data (curItemSA, curItemWdt)
59 SetupItemData:
60   inc   a
61   jr    z,.noitem
62   ld    (.itemdataVar),hl
63   dec   a
64   ld    e,a
65   ld    d,0
66   ld    hl,(curMenu)
67   add   hl,de
68   add   hl,de
69   add   hl,de
70   ld    a,(WinSys.origx)
71   add   (hl)
72   ld    e,a
73   inc   hl
74   ld    a,(WinSys.origy)
75   add   (hl)
76   ld    d,a
77   inc   hl
78   ld    b,(hl)
79   ; d: y (charz)
80   ; e: x (charz)
81   ld    a,d
82   and   #18
83   or    #40
84   ld    h,a
85   ld    a,d
86   rrca
87   rrca
88   rrca
89   and   #E0
90   or    e
91   ld    l,a
92   ex    de,hl
93   ld    hl,.itemdataVar
94 .itemdataVar: equ $-2
95   ld    (hl),e
96   inc   hl
97   ld    (hl),d
98   inc   hl
99   ld    (hl),b
100   ret
101 .noitem:
102   inc   hl
103   ld    (hl),a
104   ret
107 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
108 ;; in:
109 ;;   c: x
110 ;;   b: y
111 ;; out:
112 ;;   a: selected item or #ff
113 ;;   af,bc,de,hl: destroyed
114 MenuTest:
115   srl   b,b,b
116   srl   c,c,c
117   ;
118   ld    hl,(curMenu)
119   ld    d,0         ; item counter
120 .loop:
121   ; x
122   ld    a,(hl)
123   cp    #ff
124   jr    z,.quit
125   ld    a,(WinSys.origx)
126   add   (hl)
127   inc   hl
128   ld    e,a         ; e = menu_x
129   ; y
130   ld    a,(WinSys.origy)
131   add   (hl)
132   inc   hl
133   cp    b
134   jr    nz,.next
135   ld    a,c         ; a = x
136   sub   e
137   jr    c,.next     ; if x < menu_x: continue
138   cp    (hl)
139   jr    nc,.next    ; if x >= menu_x+menu_width: continue
140   ; selected item found
141   ld    a,d
142 .quit:
143   ld    (lastSelectedItem),a
144   ret
145 .next:
146   ; advance to the next item
147   inc   hl
148   ; increase item counter
149   inc   d
150   jr    .loop
153 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
154 ;; check if arrow is inside window
155 ;; out:
156 ;;   carry: =1 if outsize
157 ;;   af,de,hl: dead
158 IsArrowInWindow:
159   ld    hl,WinSys.orig
160   ld    de,(WinSys.wsize)
161   ; test x
162   ld    a,(WinArrow.curX)
163   and   #F8
164   rrca:rrca:rrca  ; /8
165   sub   (hl)      ; -origx
166   ret   c         ; outside
167   sub   e         ; -width
168   ccf
169   ret   c         ; outsize
170   ; x ok
171   ; test y
172   inc   hl
173   ld    a,(WinArrow.curY)
174   and   #F8
175   rrca:rrca:rrca  ; /8
176   sub   (hl)      ; -origy
177   ret   c         ; outside
178   sub   d         ; -height
179   ccf
180   ret
183 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
184 ;; ÎÁÍÁÌÀÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
185 ;; ÄÅÌÁÅÍ halt
186 ;; out:
187 ;;   af,af',bc,de,hl,bc',de',hl': ÄÏÈÌÙÅ
188 ShowArrow:
189   call  WinMouse.Scan   ; ÜÔÏ ÞÔÏÂÙ ÍÙÛØ ÎÅ ÅÌÏÚÉÌÁÓØ
190   ld    hl,(WinArrow.curX)
191   ld    (WinArrow.newX),hl
192   jp    ForcedRedrawArrow
195 tmpItemSA:   dw 0  ; current item's screen address
196 tmpItemWdt:  db 0
198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
199 ;; out:
200 ;;   af,af',bc,de,hl,bc',de': destroyed
201 RedrawArrow:
202   ld    bc,(WinArrow.newX)
203   ld    hl,(WinArrow.curX)
204   ld    a,l
205   cp    c
206   jr    nz,ForcedRedrawArrow
207   ld    a,h
208   cp    b
209   ret   z
210 ForcedRedrawArrow:
211   ld    bc,(WinArrow.newX)
212   call  MenuTest
213   ld    hl,tmpItemSA
214   call  SetupItemData
215 @redrawArrowHalt:
216   halt
217  IFX __TEST_INTR_TIME__
218   ld    a,2
219   out   (#fe),a
220  ENDIF
221   call  WinArrow.Rest
222   ld    hl,lastItemSA
223   call  InverseMenuBar
224   ld    hl,tmpItemSA
225   call  InverseMenuBar
226   ld    hl,(WinArrow.newX)
227   ld    (WinArrow.curX),hl
228   call  WinArrow.Draw
229  IFX __TEST_INTR_TIME__
230   xor   a
231   out   (#fe),a
232  ENDIF
233   ld    hl,(tmpItemSA)
234   ld    (lastItemSA),hl
235   ld    a,(tmpItemWdt)
236   ld    (lastItemWdt),a
237   ret
240 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241 ;; redraw arrow from interrupt handler
242 ;; out:
243 ;;   af,af',bc,de,hl,bc',de': destroyed
244 RedrawArrowFromIntr:
245   xor   a
246   ld    (redrawArrowHalt),a
247   call  RedrawArrow
248   ld    a,#76  ; halt
249   ld    (redrawArrowHalt),a
250   ret
253 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
254 ;; ÓÐÒÑÞÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
255 ;; out:
256 ;;   af',bc,de,hl: ÄÏÈÌÙÅ
257 HideArrow:
258   push  af
259   call  WinArrow.Rest
260   ld    hl,lastItemSA
261   call  InverseMenuBar
262   xor   a
263   ld    (lastItemSA+1),a
264   pop   af
265   ret
268 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
269 ;; ÐÒÏÉÎÉÔÉÍ ÍÅÎÀÈÕ, ÐÏÄÓ×ÅÔÉÍ ÎÕÖÎÙÊ ÐÕÎËÔ, ÚÁÄ×ÉÎÅÍ ÎÁ ÎÅÇÏ ÓÔÒÅÌËÕ
270 ;; in:
271 ;;   hl: ptr to "menu info" (can be 0)
272 ;;   a: item to set cursor on (#ff: none)
273 ;; out:
274 ;;   af,af',bc,de,hl,bc',de': destroyed
275 InitMenu:
276   ld    e,a
277   ld    d,0
278   ld    a,h
279   or    l
280   jr    nz,.ok
281   ld    hl,dummyMenu
282 .ok:
283   ld    (curMenu),hl
284   ld    a,e
285   ld    (lastSelectedItem),a
286   cp    #ff
287   jr    z,.nodef
288   ; set arrow to item a
289   add   hl,de
290   add   hl,de
291   add   hl,de
292   ;
293   ld    a,(WinSys.origx)
294   add   (hl)
295   inc   hl
296   add   a,a
297   add   a,a
298   add   a,a
299   ld    e,a
300   ;
301   ld    a,(WinSys.origy)
302   add   (hl)
303   inc   hl
304   add   a,a
305   add   a,a
306   add   a,a
307   add   a,4
308   ld    d,a
309   ;
310   ld    a,(hl)
311   add   a,a
312   add   a,a
313   add   a,e
314   ld    e,a
315   ;
316   ld    (WinArrow.curX),de
317 .nodef:
318   xor   a
319   ld    (tmpItemSA+1),a
320   ld    (lastItemSA+1),a
321   call  WaitFireRelease
322   jp    ShowArrow
325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
326 ;; ÏÄÉΠÃÉËÌ "ÍÅÎÀÈÉ"
327 ;; out:
328 ;;   a: menu item number/#ff (carry set); dirt (carry reset)
329 ;;   carry flag: fire pressed on an item or outside the window
330 ;;   carry reset: fire not pressed or not an any item
331 ;;   f,af',bc,de,hl,bc',de',hl': destroyed
332 RunMenuOnce:
333   call  WinMouse.Scan
334   jr    c,.mactionok
335   call  WinInput.StickMoves
336   ld    a,c
337   or    a
338   ret   z      ; return if no stick events
339 .mactionok:
340   call  RedrawArrow
341   ; check "fire"
342   ld    a,(WinInput.joystate)
343   rra
344   ret   nc     ; return if fire isn't pressed
345   call  IsArrowInWindow
346   jr    c,.outside
347   ld    a,(lastSelectedItem)
348   cp    #ff
349   ret
350 .outside:
351   ; the arrow is outside the window
352   ld    a,#ff
353   ld    (lastSelectedItem),a
354   scf
355   ret
358 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
359 ;; ÂÅÇÁÅÍ ÐÏ ÍÅÎÀÈÅ, Öģ͠"fire"
360 ;; out:
361 ;;   a: selected item (or #ff ÅÖÅÌÉ ×ÎÅ ÏËÏÛËÁ)
362 ;;   f,af',bc,de,hl,bc',de',hl': destroyed
363 RunMenuLoop:
364   call  RunMenuOnce
365   jr    nc,RunMenuLoop
366   ret
369 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370 ;; ÓÐÒÑÞÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
371 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÏÔÐÕÓÔÉÔ "fire"
372 ;; out:
373 ;;   af',bc,de,hl: ÄÏÈÌÙÅ
374 HideWaitRelease:
375   call  HideArrow
378 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
379 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÏÔÐÕÓÔÉÔ "fire"
380 ;; out:
381 ;;   bc,de,hl: ÄÏÈÌÙÅ
382 WaitFireRelease:
383   push  af
384 .loop:
385   call  WinMouse.ScanButtons
386   ; ÅÓÌÉ ÍÙÛËÉ ÎÅÔ, ÔÏ ÂÉÔ 0 ÓÂÒÏÛÅÎ, ÉÎÁÞÅ ÕÓÔÁÎÏ×ÌÅΠÐÒÉ ÎÁÖÁÔÏÊ ËÎÏÐËÅ
387   and   #01
388   jr    nz,.loop
389   call  WinInput.SticksInput
390   bit   0,c
391   jr    nz,.loop
392   pop   af
393   ret
396 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
397 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÎÁÄÁ×ÉÔ "fire"
398 ;; out:
399 ;;   bc,de,hl: ÄÏÈÌÙÅ
400 WaitFirePress:
401   push  af
402 .loop:
403   call  WinMouse.ScanButtons
404   ; ÅÓÌÉ ÍÙÛËÉ ÎÅÔ, ÔÏ ÂÉÔ 0 ÓÂÒÏÛÅÎ, ÉÎÁÞÅ ÕÓÔÁÎÏ×ÌÅΠÐÒÉ ÎÁÖÁÔÏÊ ËÎÏÐËÅ
405   and   #01
406   jr    nz,.quit
407   call  WinInput.SticksInput
408   bit   0,c
409   jr    z,.loop
410 .quit:
411   pop   af
412   ret
415 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
416 ;; ÕÓÔÁÎÏ×ÉÔØ ÎÏ×ÙÅ ËÏÏÒÄÉÎÁÔÙ ÓÔÒÅÌÏÞËÉ, ÐÏÄÓ×ÅÔÉÔØ ÍÅÎÀ, ÅÓÌÉ ÎÁÄÏ
417 ;; ÅÓÌÉ ÒÉÓÕÅÍ ÓÔÒÅÌÏÞËÕ, ÔÏ ÄÅÌÁÅÍ É halt
418 ;; in:
419 ;;   e: x
420 ;;   d: y
421 ;;   carry flag set: draw arrow
422 ;; out:
423 ;;   af,af',bc,de,hl,bc',de',hl': ÄÏÈÌÙÅ
424 SetArrowXY:
425   ld   (WinArrow.curX),de
426   jp   c,ForcedRedrawArrow
427   ret
430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
431 ;; ÕÓÔÁÎÏ×ÉÍ ÎÏ×ÙÊ ÓÐÒÁÊÔ ÓÔÒÅÌÏÞËÉ
432 ;; ÅÓÌÉ ÒÉÓÕÅÍ ÓÔÒÅÌÏÞËÕ, ÔÏ ÄÅÌÁÅÍ É halt
433 ;; in:
434 ;;   hl: ptr to arrow sprite
435 ;;   carry flag set: draw arrow
436 ;; out:
437 ;;   af,af',bc,de,hl,bc',de',hl': ÄÏÈÌÙÅ
438 SetArrowPtr:
439   ld    (WinArrow.sprAddr),hl
440   jp    c,ForcedRedrawArrow
441   ret
444 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
445 ;; in:
446 ;;   a: index
447 ;;   hl: table
448 ;; out:
449 ;;   af: dead
450 ;;   hl: word in table at given index (or 00 for #ff)
451 ;;   zero flag: set if hl is zero
452 GetTableWord:
453   cp    #ff
454   jr    z,.zeroq
455   push  de
456   ld    e,a
457   ld    d,0
458   ex    de,hl
459   add   hl,hl
460   add   hl,de
461   ld    e,(hl)
462   inc   hl
463   ld    h,(hl)
464   ld    l,e
465   pop   de
466 .done:
467   ld    a,h
468   or    l
469   ret
470 .zeroq:
471   ld    hl,0
472   jr    .done
475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
476 ;; do 'call hl'
477 CallHL:
478   jp   hl
481   endmodule