winsys: added WinInput.ReadStrZ
[urasm.git] / libs / winsys / wininput.zas
blobdba5ee523184517f2d2d820a80f9b0375c190c37
1   module WinInput
2   ;; requires: WinStick, WinMouse, WinArrow
4 OPT_SAME_DIR equ 0
6 ;STICK_ACCEL0 equ 12
7 ;STICK_ACCEL1 equ 16
8 ;STICK_ACCEL2 equ 20
9 ;STICK_ACCEL3 equ 25
11 stickAccelPtr: dw stickAccel
13 stickAccel:
14   db 12,16,20,25,30
15   db 0
18 joystate: db 0
19 ; joycount is the "stick repeat counter"
20 ; (used to acceleration)
21 joycount: db 0
24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;; ÓÍÏÔÒÉÍ, Ä£ÒÇÁÌÉ ÌÉ ËÌÁ×Õ ÉÌÉ ÄÖÏÊÓÔÉËÉ,
26 ;; ×ÙÞÉÓÌÑÅÍ ÎÏ×ÙÅ ËÏÏÒÄÉÎÁÔÙ ÓÔÒÅÌËÉ
27 ;; out:
28 ;;   c: stick flags
29 ;;   af,b,de,hl: ÇÒÑÚØ
30 StickMoves:
31   call SticksInput
32   ;
33   ld   a,(joycount)
34   inc  a
35   jr   nz,.nowrap
36   dec  a
37 .nowrap:
38   ld   (joycount),a
39   ld   d,a
40  IFX OPT_SAME_DIR
41   ld   hl,joystate
42   ld   a,c
43   cp   (hl)
44   jr   z,.samedir
45   ld   d,a
46   xor  a
47   ld   (joycount),a
48   ld   a,d
49   ld   d,0
50 .samedir:
51   ld   (hl),a
52   ld   a,c
53  ELSE
54   ld   a,c
55   ld   (joystate),a
56  ENDIF
57   or   a
58   jr   nz,.moved
59   ld   (joycount),a
60   ret
61 .moved:
62   ; acceleration
63   ; d: joycount
64   ; e: delta
65   ld   hl,(stickAccelPtr)
66   ld   e,1
67 .accelloop:
68   ld   a,(hl)
69   or   a
70   jr   z,.acceldone
71   cp   d
72   jr   nc,.acceldone
73   inc  e
74   inc  hl
75   jr   .accelloop
76 .acceldone:
77   ; left?
78   ld   hl,(WinArrow.curX)
79   bit  4,c
80   jr   z,.noleft
81   ld   a,l
82   sub  e
83   jr   nc,$+3   ; skip next instr.
84   xor  a
85   ld   l,a
86 .noleft:
87   ; right?
88   bit  3,c
89   jr   z,.noright
90   ld   a,l
91   add  a,e
92   jr   nc,$+4  ; skip next instr.
93   ld   a,#ff
94   ld   l,a
95 .noright:
96   ; up?
97   bit  2,c
98   jr   z,.noup
99   ld   a,h
100   sub  e
101   jr   nc,$+3  ; skip next instr.
102   xor  a
103   ld   h,a
104 .noup:
105   ; down?
106   bit  1,c
107   jr   z,.nodown
108   ld   a,h
109   add  a,e
110   cp   191
111   jr   c,$+4  ; skip next instr.
112   ld   a,191
113   ld   h,a
114 .nodown:
115   ld   (WinArrow.newX),hl
116   ret
119 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
120 ;; ÐÒÏ×ÅÒѣ͠ËÌÁ×Õ É ÄÖÏÊÓÔÉËÉ
121 ;; out:
122 ;;   a, c: state
123 ;;   f,b,de,hl: destroyed
124 SticksInput:
125   call WinStick.ReadMoves
126   ; kempston joystick
127   ld   a,(WinStick.kempston_here)
128   and  #01
129   jr   z,.nokj
130   ;
131   xor  a
132   in   a,(#1F)
133   inc  a
134   jr   z,.nokj
135   ld   hl,WinStick.keystick_kempston
136   push bc
137   call WinStick.ReadStick
138   pop  bc
139 .nokj:
140   or   c
141   ld   c,a
142   ret
145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
146 ;; test for kempston joystick & kempston mouse presence
147 ;; out:
148 ;;   a: flags
149 ;;   f: dead
150 TestJoyMouse:
151   push hl
152   ld   hl,WinStick.kempston_here
153   call WinStick.TestKempstonJ
154   ld   (hl),a
155   call WinMouse.TestKempstonM
156   or   (hl)
157   ld   (hl),a
158   pop  hl
159   ret
162 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
163 ;; return when any key pressed
164 WaitKeysPress:
165   push af
166 .loop:
167   xor  a
168   in   a,(#FE)
169   cpl
170   and  #1F
171   jr   z,.loop
172   pop  af
173   ret
176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
177 ;; return when no keys are pressed
178 WaitKeysRelease:
179   push af
180 .loop:
181   xor  a
182   in   a,(#FE)
183   cpl
184   and  #1F
185   jr   nz,.loop
186   pop  af
187   ret
190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
191 ;; test for CS and SS
192 ;; out:
193 ;;   carry: CS
194 ;;   zerof: SS
195 TestKeyShifts:
196   push hl
197   ld   l,a
198   ; SS
199   ld   a,#7f
200   in   a,(#fe)
201   ld   h,a
202   ; CS
203   ld   a,#fe
204   in   a,(#fe)
205   and  #01
206   jr   z,.csdown
207   bit  1,h
208   jr   .quit
209 .csdown:
210   bit  1,h
211   scf
212 .quit:
213   ld   a,l
214   pop  hl
215   ret
218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219 ;; don't wait for keypress; return char or carry reset
220 ;; in:
221 ;;   carry: don't react to shifts, if set
222 ;; out:
223 ;;   a: key number (1-40) or 0
224 ;;   f: dead
225 ;;   carry: set if key was decoded
226 ;; note:
227 ;;   30: CS
228 ;;   31: SS
229 InKeyScanCode:
230   push hl,bc
231   ld   hl,.keypressed
232   jr   c,.noshiftreaction
233   ld   hl,.nextbit
234 .noshiftreaction:
235   ld   (.jpaddr),hl
236   ;
237   ld   l,0
238   ld   bc,#7ffe
239 .nextrow:
240   in   a,(c)
241   cpl
242   and  #1f
243 .jpaddr: equ $+1
244   jp   nz,.keypressed
245 .skiprow:
246  DUP 5
247   inc  l
248  EDUP
249   rrc  b
250   jr   c,.nextrow
251   xor  a
252 .quit:
253   pop  bc,hl
254   ret
255 .keypressed:
256   ; check for CS and SS
257   ld   h,a
258   ld   a,b
259   cp   #7f
260   jr   nz,.notss
261   res  1,h
262 .notss:
263   cp   #fe
264   jr   nz,.notcs
265   res  0,h
266 .notcs:
267   ld   a,h
268   or   a
269   jr   z,.skiprow
270 .nextbit:
271   inc  l
272   rra
273   jr   nc,.nextbit
274   ld   a,l
275   scf
276   jr   .quit
279 ;; bit 0: caps
280 ;; bit 1: russian
281 keybMode: db 0
284 ; 30:CS; 31:SS
285 ;.keytab: DEFM  ' ',31,'MNB',13,'LKJHPOIUY0987612345QWERTASDFG',30,'ZXCV'
286 ; keyboard tables
287 keytabEL: db  ' ',0,'mnb',13,'lkjhpoiuy0987612345qwertasdfg',0,'zxcv'
288 keytabEC: db  ' ',0,'MNB',13,'LKJHPOIUY0987612345QWERTASDFG',0,'ZXCV'
289 keytabEU: db  ' ',0,'MNB',13,'LKJHPOIUY',12,9,8,7,6,27,2,3,4,5,'QWERTASDFG',0,'ZXCV'
290 keytabES: db  ' ',0,'.,*',13,'=+-^',34,59,127,'][_)(',39,'&!@#$%',0,0,0,'<>~|',92,'{}',0,':`?/'
293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294 ;; don't wait for keypress; return char or carry reset
295 ;; out:
296 ;;   a: key code or 0
297 ;;   f: dead
298 ;;   carry: set if key was decoded
299 InKey:
300   scf
301   call InKeyScanCode
302   ret  nc
303   push hl,de
304   call TestKeyShifts
305   ld   hl,keytabES-1
306   jr   z,.getcode
307   ld   hl,keytabEU-1
308   jr   c,.getcode
309   ; no shifts
310   ld   hl,keybMode
311   bit  0,(hl)
312   ld   hl,keytabEL-1
313   jr   z,.getcode
314   ld   hl,keytabEC-1
315 .getcode:
316   ld   e,a
317   ld   d,0
318   add  hl,de
319   ld   a,(hl)
320   pop  de,hl
321   or   a
322   scf
323   ret  nz
324   ccf
325   ret
328 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
329 ;; wait for keypress; return char
330 ;; out:
331 ;;   a: key code
332 ReadKey:
333   call InKey
334   cp   13
335   ret  z
336   cp   32
337   jr   c,ReadKey
338   ret
341 repeatDelay: db 30
342 repeatAuto: db 3
343 cursorBlink: db 15
345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
346 ;; read string
347 ;; in:
348 ;;   hl: destination buffer (must be strz)
349 ;;   c: max length
350 ;; out:
351 ;;   a: len
352 ;;   carry: set if esc was pressed
353 ReadStrZ:
354   push bc,de,hl
355   ld   a,c
356   ld   (strmaxlen),a
357   ld   (rstrbuf),hl
358   ld   hl,(WinSys.printxy)
359   ld   (rstrxy),hl
360   ld   a,0
361   ld   (.curcode),a
362   ld   a,(cursorBlink)
363   ld   (repeatBlink),a
364   or   a
365   ld   a,1
366   jr   nz,.initblink
367   dec  a
368 .initblink:
369   ld   (.blinkvar),a
370 .resetrepeat:
371   ld   a,(repeatDelay)
372   ld   (repeatCnt),a
373   xor  a
374   ld   (repeatPK),a
375 .waitkey:
376 .curcode: equ $+1
377   ld   a,0
378   add  a,179
379   call .printStr
380   ld   hl,repeatBlink
381   dec  (hl)
382   jr   nz,.notblink
383   ld   hl,.curcode
384 .blinkvar: equ $+1
385   ld   a,1
386   xor  (hl)
387   ld   (hl),a
388   ld   a,(cursorBlink)
389   ld   (repeatBlink),a
390 .notblink:
391   halt
392   scf
393   call WinInput.InKey
394   cp   2
395   jr   nz,.notcapstoggle
396   ld   hl,keybMode
397   ld   a,1
398   xor  (hl)
399   ld   (hl),a
400   jr   .waitkey
401 .notcapstoggle:
402   cp   12
403   jr   z,.gotkey
404   cp   13
405   jr   z,.doenter
406   cp   27
407   jr   z,.doesc
408   cp   32
409   jr   nc,.gotkey
410   ; no key, reset counters
411   jr   .resetrepeat
412 .gotkey:
413   ld   b,a  ; save key
414   ld   a,(repeatPK)
415   cp   b
416   jr   nz,.processkey
417   ld   hl,repeatCnt
418   dec  (hl)
419   jr   nz,.waitkey
420   ; set new repeat
421   ld   a,(repeatAuto)
422   ld   (hl),a
423 .processkey:
424   ld   a,b
425   ld   hl,(rstrbuf)
426   ld   (repeatPK),a
427   cp   12
428   jr   z,.dobs
429   push af
430   ld   hl,(rstrbuf)
431   call strzlen  ; hl points to 0
432 @strmaxlen: equ $+1
433   ld   a,0
434   inc  b
435   cp   b
436   jr   c,.toolong
437 .addsym:
438   pop  af
439   ld   (hl),a
440   inc  hl
441 .doagain:
442   ld   (hl),0
443   ld   a,179
444   call .printStr
445   jr   .waitkey
446 .dobs:
447   ld   a,180
448   call .printStr
449   ld   hl,(rstrbuf)
450   call strzlen  ; hl points to 0
451   dec  hl
452   jr   .doagain
453 .toolong:
454   ; string too long
455   pop  af
456   jp   .waitkey
458 .doesc:
459   ld   a,#37  ; scf
460   ld   (.setcf),a
461   jr   .doexit
462 .doenter:
463   ld   a,0    ; nop
464   ld   (.setcf),a
465 .doexit:
466   ld   a,180
467   call .printStr
468   ld   hl,(rstrbuf)
469   call strzlen
470   ld   a,b
471   or   a
472 .setcf:
473   nop
475   pop  hl,de,bc
476   ret
478 ; a: 179(cur) or 180(space)
479 .printStr:
480   push af
481 @rstrxy: equ $+1
482   ld   hl,0
483   ld   (WinSys.printxy),hl
484 @rstrbuf: equ $+1
485   ld   hl,0
486   call WinPrint.PrintStrZ
487   pop  af
488   call WinPrint.PrintChar
489   ret
491 repeatCnt: db 0
492 repeatPK: db 0
493 repeatBlink: db 0
496 strzlen:
497   ld   b,0
498 .loop:
499   ld   a,(hl)
500   or   a
501   ret  z
502   inc  b
503   inc  hl
504   jr   .loop
507   endmodule