added "printf[0a]", and "error"
[urasm.git] / libs / winsys / winmenu.zas
blobed85f1fca73b8c55324467ae8a85ee0de0ef39b2
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 .invLVar: equ $+1
49   ld   e,0
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 .itemdataVar: equ $+1
94   ld   hl,.itemdataVar
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
106 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
107 ;; in:
108 ;;   c: x
109 ;;   b: y
110 ;; out:
111 ;;   a: selected item or #ff
112 ;;   af,bc,de,hl: destroyed
113 MenuTest:
114   srl b:srl b:srl b
115   srl c:srl c:srl c
116   ;
117   ld   hl,(curMenu)
118   ld   d,0         ; item counter
119 .loop:
120   ; x
121   ld   a,(hl)
122   cp   #ff
123   jr   z,.quit
124   ld   a,(WinSys.origx)
125   add  (hl)
126   inc  hl
127   ld   e,a         ; e = menu_x
128   ; y
129   ld   a,(WinSys.origy)
130   add  (hl)
131   inc  hl
132   cp   b
133   jr   nz,.next
134   ld   a,c         ; a = x
135   sub  e
136   jr   c,.next     ; if x < menu_x: continue
137   cp   (hl)
138   jr   nc,.next    ; if x >= menu_x+menu_width: continue
139   ; selected item found
140   ld   a,d
141 .quit:
142   ld   (lastSelectedItem),a
143   ret
144 .next:
145   ; advance to the next item
146   inc  hl
147   ; increase item counter
148   inc  d
149   jr   .loop
152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
153 ;; check if arrow is inside window
154 ;; out:
155 ;;   carry: =1 if outsize
156 ;;   af,de,hl: dead
157 IsArrowInWindow:
158   ld   hl,WinSys.orig
159   ld   de,(WinSys.wsize)
160   ; test x
161   ld   a,(WinArrow.curX)
162   and  #F8
163   rrca:rrca:rrca  ; /8
164   sub  (hl)       ; -origx
165   ret  c          ; outside
166   sub  e          ; -width
167   ccf
168   ret  c          ; outsize
169   ; x ok
170   ; test y
171   inc  hl
172   ld   a,(WinArrow.curY)
173   and  #F8
174   rrca:rrca:rrca  ; /8
175   sub  (hl)       ; -origy
176   ret  c          ; outside
177   sub  d          ; -height
178   ccf
179   ret
182 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183 ;; ÎÁÍÁÌÀÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
184 ;; ÄÅÌÁÅÍ halt, ÓÏÓÔÏÑÎÉÅ ÐÒÅÒÙ×ÁÎÉÊ -- ÐÏÆÉÇÕ, ×ÏÓÓÔÁÎÏ×ÉÍ
185 ;; out:
186 ;;   af,af',bc,de,hl,bc',de',hl': ÄÏÈÌÙÅ
187 ShowArrow:
188   call WinMouse.Scan   ; ÜÔÏ ÞÔÏÂÙ ÍÙÛØ ÎÅ ÅÌÏÚÉÌÁÓØ
189   ld   hl,(WinArrow.curX)
190   ld   (WinArrow.newX),hl
191   jp   ForcedRedrawArrow
194 tmpItemSA:   dw 0  ; current item's screen address
195 tmpItemWdt:  db 0
197 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198 ;; out:
199 ;;   af,af',bc,de,hl,bc',de': destroyed
200 RedrawArrow:
201   ld   bc,(WinArrow.newX)
202   ld   hl,(WinArrow.curX)
203   ld   a,l
204   cp   c
205   jr   nz,ForcedRedrawArrow
206   ld   a,h
207   cp   b
208   ret  z
209 ForcedRedrawArrow:
210   ld   bc,(WinArrow.newX)
211   call MenuTest
212   ld   hl,tmpItemSA
213   call SetupItemData
214 @redrawArrowHalt:
215   halt
216  IFX __TEST_INTR_TIME__
217   ld  a,2
218   out  (#fe),a
219  ENDIF
220   call WinArrow.Rest
221   ld   hl,lastItemSA
222   call InverseMenuBar
223   ld   hl,tmpItemSA
224   call InverseMenuBar
225   ld   hl,(WinArrow.newX)
226   ld   (WinArrow.curX),hl
227   call WinArrow.Draw
228  IFX __TEST_INTR_TIME__
229   xor  a
230   out  (#fe),a
231  ENDIF
232   ld   hl,(tmpItemSA)
233   ld   (lastItemSA),hl
234   ld   a,(tmpItemWdt)
235   ld   (lastItemWdt),a
236   ret
239 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240 ;; redraw arrow from interrupt handler
241 ;; out:
242 ;;   af,af',bc,de,hl,bc',de': destroyed
243 RedrawArrowFromIntr:
244   xor  a
245   ld   (redrawArrowHalt),a
246   call RedrawArrow
247   ld   a,#76  ; halt
248   ld   (redrawArrowHalt),a
249   ret
252 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
253 ;; ÓÐÒÑÞÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
254 ;; out:
255 ;;   af',bc,de,hl: ÄÏÈÌÙÅ
256 HideArrow:
257   push af
258   call WinArrow.Rest
259   ld   hl,lastItemSA
260   call InverseMenuBar
261   xor  a
262   ld   (lastItemSA+1),a
263   pop  af
264   ret
267 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
268 ;; ÐÒÏÉÎÉÔÉÍ ÍÅÎÀÈÕ, ÐÏÄÓ×ÅÔÉÍ ÎÕÖÎÙÊ ÐÕÎËÔ, ÚÁÄ×ÉÎÅÍ ÎÁ ÎÅÇÏ ÓÔÒÅÌËÕ
269 ;; in:
270 ;;   hl: ptr to "menu info" (can be 0)
271 ;;   a: item to set cursor on (#ff: none)
272 ;; out:
273 ;;   af,af',bc,de,hl,bc',de': destroyed
274 InitMenu:
275   ld   e,a
276   ld   d,0
277   ld   a,h
278   or   l
279   jr   nz,.ok
280   ld   hl,dummyMenu
281 .ok:
282   ld   (curMenu),hl
283   ld   a,e
284   ld   (lastSelectedItem),a
285   cp   #ff
286   jr   z,.nodef
287   ; set arrow to item a
288   add  hl,de
289   add  hl,de
290   add  hl,de
291   ;
292   ld   a,(WinSys.origx)
293   add  (hl)
294   inc  hl
295   add  a,a
296   add  a,a
297   add  a,a
298   ld   e,a
299   ;
300   ld   a,(WinSys.origy)
301   add  (hl)
302   inc  hl
303   add  a,a
304   add  a,a
305   add  a,a
306   add  a,4
307   ld   d,a
308   ;
309   ld   a,(hl)
310   add  a,a
311   add  a,a
312   add  a,e
313   ld   e,a
314   ;
315   ld   (WinArrow.curX),de
316 .nodef:
317   xor  a
318   ld   (tmpItemSA+1),a
319   ld   (lastItemSA+1),a
320   call WaitFireRelease
321   jp   ShowArrow
324 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
325 ;; ÏÄÉΠÃÉËÌ "ÍÅÎÀÈÉ"
326 ;; out:
327 ;;   a: menu item number/#ff (carry set); dirt (carry reset)
328 ;;   carry flag: fire pressed on an item or outside the window
329 ;;   carry reset: fire not pressed or not an any item
330 ;;   f,af',bc,de,hl,bc',de',hl': destroyed
331 RunMenuOnce:
332   call WinMouse.Scan
333   jr   c,.mactionok
334   call WinInput.StickMoves
335   ld   a,c
336   or   a
337   ret  z      ; return if no stick events
338 .mactionok:
339   call RedrawArrow
340   ; check "fire"
341   ld   a,(WinInput.joystate)
342   rra
343   ret  nc     ; return if fire isn't pressed
344   call IsArrowInWindow
345   jr   c,.outside
346   ld   a,(lastSelectedItem)
347   cp   #ff
348   ret
349 .outside:
350   ; the arrow is outside the window
351   ld   a,#ff
352   ld   (lastSelectedItem),a
353   scf
354   ret
357 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
358 ;; ÂÅÇÁÅÍ ÐÏ ÍÅÎÀÈÅ, Öģ͠"fire"
359 ;; out:
360 ;;   a: selected item (or #ff ÅÖÅÌÉ ×ÎÅ ÏËÏÛËÁ)
361 ;;   f,af',bc,de,hl,bc',de',hl': destroyed
362 RunMenuLoop:
363   call RunMenuOnce
364   jr   nc,RunMenuLoop
365   ret
368 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
369 ;; ÓÐÒÑÞÅÍ ÓÔÒÅÌÏÞËÕ. ÐÒÅÄÙÄÕÝÅŠţ ÓÏÓÔÏÑÎÉÅ ÐÏÆÉÇÕ
370 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÏÔÐÕÓÔÉÔ "fire"
371 ;; out:
372 ;;   af',bc,de,hl: ÄÏÈÌÙÅ
373 HideWaitRelease:
374   call HideArrow
377 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
378 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÏÔÐÕÓÔÉÔ "fire"
379 ;; out:
380 ;;   bc,de,hl: ÄÏÈÌÙÅ
381 WaitFireRelease:
382   push af
383 .loop:
384   call WinMouse.ScanButtons
385   ; ÅÓÌÉ ÍÙÛËÉ ÎÅÔ, ÔÏ ÂÉÔ 0 ÓÂÒÏÛÅÎ, ÉÎÁÞÅ ÕÓÔÁÎÏ×ÌÅΠÐÒÉ ÎÁÖÁÔÏÊ ËÎÏÐËÅ
386   and  #01
387   jr   nz,.loop
388   call WinInput.SticksInput
389   bit  0,c
390   jr   nz,.loop
391   pop  af
392   ret
395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
396 ;; ÖÄ£Í, ÐÏËÁ ÀÚ×ÅÒØ ÎÁÄÁ×ÉÔ "fire"
397 ;; out:
398 ;;   bc,de,hl: ÄÏÈÌÙÅ
399 WaitFirePress:
400   push af
401 .loop:
402   call WinMouse.ScanButtons
403   ; ÅÓÌÉ ÍÙÛËÉ ÎÅÔ, ÔÏ ÂÉÔ 0 ÓÂÒÏÛÅÎ, ÉÎÁÞÅ ÕÓÔÁÎÏ×ÌÅΠÐÒÉ ÎÁÖÁÔÏÊ ËÎÏÐËÅ
404   and  #01
405   jr   nz,.quit
406   call WinInput.SticksInput
407   bit  0,c
408   jr   z,.loop
409 .quit:
410   pop  af
411   ret
414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
415 ;; ÕÓÔÁÎÏ×ÉÔØ ÎÏ×ÙÅ ËÏÏÒÄÉÎÁÔÙ ÓÔÒÅÌÏÞËÉ, ÐÏÄÓ×ÅÔÉÔØ ÍÅÎÀ, ÅÓÌÉ ÎÁÄÏ
416 ;; ÅÓÌÉ ÒÉÓÕÅÍ ÓÔÒÅÌÏÞËÕ, ÔÏ ÄÅÌÁÅÍ É halt
417 ;; ÓÏÓÔÏÑÎÉÅ ÐÒÅÒÙ×ÁÎÉÊ -- ÐÏÆÉÇÕ, ×ÏÓÓÔÁÎÏ×ÉÍ
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   ret nc
427   ; ÄÁÌØÛÅ ÓÍÅÌÏ Éģ͠ÎÁ ShowArrow
430 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
431 ;; ÕÓÔÁÎÏ×ÉÍ ÎÏ×ÙÊ ÓÐÒÁÊÔ ÓÔÒÅÌÏÞËÉ
432 ;; ÅÓÌÉ ÒÉÓÕÅÍ ÓÔÒÅÌÏÞËÕ, ÔÏ ÄÅÌÁÅÍ É halt
433 ;; ÓÏÓÔÏÑÎÉÅ ÐÒÅÒÙ×ÁÎÉÊ -- ÐÏÆÉÇÕ, ×ÏÓÓÔÁÎÏ×ÉÍ
434 ;; in:
435 ;;   hl: ptr to arrow sprite
436 ;;   carry flag set: draw arrow
437 ;; out:
438 ;;   af,af',bc,de,hl,bc',de',hl': ÄÏÈÌÙÅ
439 SetArrowPtr:
440   ld   (WinArrow.sprAddr),hl
441   ret  nc
442   jp   ForcedRedrawArrow
445 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
446 ;; in:
447 ;;   a: index
448 ;;   hl: table
449 ;; out:
450 ;;   af: dead
451 ;;   hl: word in table at given index (or 00 for #ff)
452 ;;   zero flag: set if hl is zero
453 GetTableWord:
454   cp   #ff
455   jr   z,.zeroq
456   push de
457   ld   e,a
458   ld   d,0
459   ex   de,hl
460   add  hl,hl
461   add  hl,de
462   ld   e,(hl)
463   inc  hl
464   ld   h,(hl)
465   ld   l,e
466   pop  de
467 .done:
468   ld   a,h
469   or   l
470   ret
471 .zeroq:
472   ld   hl,0
473   jr   .done
476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
477 ;; do 'call hl'
478 CallHL:
479   jp  hl
482   endmodule