20 December 2011, 23:24 | #1 |
Registered User
Join Date: Nov 2010
Location: .
Posts: 386
|
[REQ:ASM] Reading a keystroke
Hello,
I'd like to read a keystroke, then based on what is pressed do <this> or <that>. I'd like to do this in the most smooth way possible, thus using input.device I've mumbled over the documentation and this post but I don't have clear what is needed to do. Basically I have to: - CreateMsgPort() - CreateIORequest() - OpenDevice() - SendIO() ? DoIO() ? and then? Do I have to prepare an InputEvent struct? Attached a tentative code snippet... Thanks |
21 December 2011, 21:02 | #2 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
First, there are a few bugs in your code, f.ex you're doing "move.l name, a0" in a few places when you probably meant to do "lea name, a0" to get its address in memory, etc.
Do you want to wait until a keyboard event occurs, or do you want to check the current state of the keyboard? If you want to wait for an event then add an input handler through input.device using the IND_ADDHANDLER and IND_REMHANDLER commands and go through all incoming events. If you want to check the current state of the keyboard then send KBD_READMATRIX to keyboard.device instead. You can find thorough examples of this in the RKM Devices. |
21 December 2011, 22:29 | #3 |
Registered User
Join Date: Nov 2010
Location: .
Posts: 386
|
Yes, basically I want to have a "listener" and note down the keys that are sent.
I'll look further into it, thanks. |
22 December 2011, 20:31 | #4 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Here's an example:
Code:
include exec/io.i include exec/nodes.i include exec/tasks.i include exec/interrupts.i include devices/input.i include devices/inputevent.i macro call xref _LVO\1 jsr _LVO\1(a6) endm section code move.l 4, a6 call CreateMsgPort move.l d0, a5 ; a5 = MsgPort move.l a5, a0 move.l #IOSTD_SIZE, d0 call CreateIORequest move.l d0, a4 ; a4 = IOStdReq lea inputdevice, a0 moveq #0, d0 move.l a4, a1 clr.l d1 call OpenDevice sub #IS_SIZE, sp move.l sp, a3 ; a3 = Interrupt ; set up our input handler sub.l a1, a1 call FindTask move.l d0, IS_DATA(a3) move.l #handlercode, IS_CODE(a3) move.b #127, LN+LN_PRI(a3) move.l #handlername, LN+LN_NAME(a3) ; add it to the chain of handlers move.l a3, IO_DATA(a4) move.w #IND_ADDHANDLER, IO_COMMAND(a4) move.l a4, a1 call DoIO ; put our task to sleep until we get the ABORT signal move.l #SIGF_ABORT, d0 call Wait ; remove the handler and clean up move.l a3, IO_DATA(a4) move.w #IND_REMHANDLER, IO_COMMAND(a4) move.l a4, a1 call DoIO add #IS_SIZE, sp move.l a4, a1 call CloseDevice move.l a4, a0 call DeleteIORequest move.l a5, a0 call DeleteMsgPort moveq #0, d0 rts ; the input handler receives a linked list of events in A0 ; and must return the new list in D0. register A1 will ; contain the IS_DATA field of the Interrupt structure handlercode move.l a0, d0 ; check if we have pressed the escape key .check cmp.b #IECLASS_RAWKEY, ie_Class(a0) bne .next cmp.w #69, ie_Code(a0) bne .next ; null this event so they keypress isn't seen by the system move.b #IECLASS_NULL, ie_Class(a0) ; signal ABORT to our task. (A1 already points to our task) movem.l d0/a6, -(sp) move.l 4, a6 move.l #SIGF_ABORT, d0 call Signal movem.l (sp)+, d0/a6 rts ; check the next event in this list .next move.l ie_NextEvent(a0), a0 move.l a0, d1 bne .check rts handlername dc.b "test input handler", 0 inputdevice dc.b "input.device", 0 |
22 December 2011, 23:13 | #5 |
Registered User
Join Date: Nov 2010
Location: .
Posts: 386
|
Uhm ... very interesting. Also, very clean and instructive code.
So, what I really need is a callback that handles the events and let me choose those interesting from those uninteresting. With such a handler I can read all events passing through the device, correct? Also, I think I see why I need such a listener: it wouldn't be possible to simply perfom a SendIO() with a CMD_READ set at IO_COMMAND offset of my IoStdReq. I would probably end up getting ... random data, I'd say, right? Not the input event I want, maybe I could intercept a mouse movement or whatever is passing through the input.device in that moment. right? Maybe the CMD_READ is more targeted to reading from a serial interface? Thanks for clarifying these points :-) |
23 December 2011, 02:28 | #6 | ||
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Quote:
Quote:
There are other methods of getting input events and data from the keyboard that might be better depending on what kind of program you're writing, but this method works for everything and should handle external HIDs such as USB keyboards without any extra code. |
||
08 August 2012, 18:47 | #7 |
Registered User
|
Similar request :
i want, per exemple, when F1 is pressed to jump to a sub-routine. is there simple way to do that ? i was thinking : wait_F1: cmp.b #$keycode,$bfec01 beq main edit: just found by pure hazard F1 is $5F None rawkey codes are corresponding : http://www.whdload.de/docs/en/rawkey.html Last edited by Foul; 08 August 2012 at 22:22. |
09 August 2012, 00:22 | #8 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
It's a bit more complicated than that. I've started writing a tutorial on the standard keyboard, joystick and mouse hardware, input routines are done but I need to write a demo program that puts it all together and shows how it works first. I'll try to finish it soon.
|
09 August 2012, 00:31 | #9 |
Registered User
|
ok excellent
Nothing Hurry, i'm just learning some asm codes writting little progs for my own usage |
09 August 2012, 01:24 | #10 | |
2 contact me: email only!
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,187
|
Quote:
Code:
move.b $bfec01,d0 ;Get 'encoded' key that pressed ror.b #1,d0 not.b d0 move.b d0,_KeyPressed ;Store rawkey that was pressed cmp.b #$50,d0 ;Check for $50 = F1 beq _F1Pressed cmp.b #$51,d0 ;Check for $51 = F2 beq _F2Pressed ... |
|
09 August 2012, 08:26 | #11 |
Registered User
|
Good to know !
|
24 July 2018, 11:47 | #12 |
Registered User
Join Date: Jun 2017
Location: Paris
Posts: 51
|
For those looking for a more hardware way, I just published two source codes for reading push / release of a key of the keyboard without using the system functions :
http://www.stashofcode.fr/routines-p...ker-sur-amiga/ First source code is for reading by polling, second source code is for reading by being interrupted. The key that is read is the ESC key. (For those who downloaded the sources: I just cleaned the code, removing anything that was not useful) Last edited by Yragael; 24 July 2018 at 12:12. Reason: Forgot to clean the code! |
24 July 2018, 12:12 | #13 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
|
Quote:
- Why do you force the code into Chip RAM? When writing a demo or a game you always have too few Chip RAM, so you shouldn't put anything there which also works (better) in Fast RAM. - Readability can be improved by limiting lines to 80 characters. I have seen some comment lines with a length of more than 20000 characters! |
|
24 July 2018, 13:57 | #14 | |
Registered User
Join Date: Jun 2017
Location: Paris
Posts: 51
|
Quote:
|
|
22 September 2018, 14:02 | #15 |
Inviyya Dude!
Join Date: Sep 2016
Location: Amiga Island
Posts: 2,798
|
Who would have thought getting a keypress is more complicated than blitting on the Amiga...
Is there something less complicated than what we see above? Coded a High Score List right now, and would like to implement some text input for the name now. But it seems I will be going for entering your name with the Joystick. That stuff above would take me ages to get right in my code, I guess. |
22 September 2018, 14:15 | #16 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
It's not really that hard. Code a level 2 interrupt routine which handles the keys and simply use a mapping table to convert the rawkey codes to ascii characters. |
|
22 September 2018, 15:14 | #17 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,501
|
And also if you want to be system compliant, using input.device, is not so hard
|
22 September 2018, 15:41 | #18 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
And if you really want to be system compliant, open an intuition screen, a window on it, and use the IDCMP system
|
22 September 2018, 16:19 | #19 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,553
|
You may also look into input.asm from the Solid Gold source (should be the same in Trap Runner). It implements a Level 2 keyboard interupt handler and a FIFO queue for fast typing. Nevertheless it's quite compact.
|
22 September 2018, 17:55 | #20 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,698
|
#ChkKey.S here is a keyboard routine with a RawKey LUT, if it helps someone.
I'm not 100% sure this routine is compatible with A2000 keyboards made by Cherry (difference in behavior). All hardware routines should be checked on this combo(!) |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
[REQ:ASM] Sprite collisions basics | jman | Coders. Tutorials | 5 | 03 September 2011 00:07 |
[REQ:ASM] Loading a static image and its palette | jman | Coders. Tutorials | 3 | 04 June 2011 14:08 |
[REQ:ASM] Assembling and running | jman | Coders. Tutorials | 9 | 07 May 2011 18:39 |
REQ:ASM getting elapsed time on A1200 | jman | Coders. Tutorials | 18 | 11 January 2011 22:24 |
REQ:ASM How to use buffers | jman | Coders. Tutorials | 7 | 01 December 2010 01:41 |
|
|