Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:18 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : INKEY$ and multiple keypresses

Author Message
karjo238
Regular Member

Joined: 12/10/2018
Location: New Zealand
Posts: 60
Posted: 03:45am 12 Oct 2018
Copy link to clipboard 
Print this post

Hey there! My name is Joseph Karl, and after finding out about Geoff Grahams Colour Maximite, I'm reliving a wave of nostalgia, programming in BASIC the way I used to many, many years ago

I have cut my teeth by making Super Star Trek work, which wasn't actually much work once you added spaces where necessary, and a real blast to play again.

From there, I decided to boldly go into something of my own (sort of), which is a version of the Atari 2600 game Missile Command.

I have done some work so far, and have had a great time making what I have done function, but I've come to an impasse.

So, I'm in the business of finding help. I stumbled upon this forum, and thought, "Hey, this looks like the place!"

My problem is that the game uses the arrow keys and the spacebar to move the cursor and fire the gun, but if I'm holding down more than one key, things don't function the way I expected. If I hold down the spacebar and then try and move the cursor, I can't. if I hold down the cursor keys and then press the spacebar, things work how I'd expect.

I'm a newbie to this version of BASIC, and I'm probably doing something silly, but right now, I don't know what that is.

This is the code. It needs cleaning up, I know, but it does mostly function.

If anybody has any ideas, this somewhat clumsy coder would be glad to hear of it.

Many thanks,

Joseph :)


Sub init
x1 = 0
y1 = 0
x2 = 0
y2 = 0
sx = 240
sy = 400
outerRad = 30
innerRad = 20
adjac = 0
oppos = 0
hypo = 0
aimX = 200
aimY = 100
Dim shell1(5,5)

LoadBMP"backg.bmp"

Sprite Load "cross.spr"
Sprite on 1,aimX,aimY

mathstuff

getpoints(angle, innerRad, outerRad)
Line(x1,y1) - (x2,y2),7
main
End Sub

Sub fireshell
q = 0
doneflag = false
Pixel(x2,y2) = 0
Do
If shell1(q,0) = 0 Then
doneflag = true
shell1(q,0) = x2
shell1(q,1) = y2
shell1(q,2) = aimX + 7
shell1(q,3) = aimY + 7
shell1(q,4) = x2
Else
q = q + 1
EndIf
Loop Until doneflag = true
drawpoint
End Sub

Sub drawpoint
For q = 0 To 4
If shell1(q,0) <> 0 Then
x = shell1(q,4)
Rem dx = endX - x2
dx = shell1(q,2) - shell1(q,0)
Rem dy = endY - y2
dy = shell1(q,3) - shell1(q,1)

y = shell1(q,1) + dy * (x - shell1(q,0)) / dx
If y >= shell1(q,3) Then
Pixel(x,y) = 7
If shell1(q,2) < shell1(q,0) Then
shell1(q,4) = shell1(q,4) - 1
Else
shell1(q,4) = shell1(q,4) + 1
EndIf

Pixel(x,y) = 0
Else
For j = 0 To 4:shell1(q,j) = 0:Next j
EndIf
EndIf
Next q

End Sub

Sub getPoints (a,r,r1)
x1 = sx + (r * Cos(a * Pi / 180))
y1 = sy + (r * Sin(a * Pi / 180))
x2 = sx + (r1 * Cos(a * Pi / 180))
y2 = sy + (r1 * Sin(a * Pi / 180))
End Sub

Sub mathstuff
oppos = sy - aimY
adjac = Abs(sx - aimX)
If adjac = 0 Then
angle = 270
Else
hypo = Sqr((oppos * oppos) + (adjac * adjac))
If aimX - sX > 0 Then
angle = 360 - arcsin(oppos / hypo) * (180 / Pi)
Else
angle = 180 + arcsin(oppos / hypo) * (180 / Pi)
EndIf
EndIf
End Sub

Function arcsin(x)
arcsin = Atn(x/Sqr(-x*x+1))
End Function

Sub clearStuff
Sprite off 1
Line(x1,y1) - (x2,y2),0
End Sub

Sub drawStuff
mathstuff
getpoints(angle, innerRad, outerRad)
Sprite on 1, aimX, aimY
Line(x1,y1) - (x2,y2),7
End Sub

Sub main

Do While 1 = 1

a = KeyDown

If a = 128 Then
clearStuff
aimY = aimY - 1
drawStuff
drawpoint
EndIf

If a = 129 Then
clearStuff
aimY = aimY + 1
drawStuff
drawpoint
EndIf

If a = 130 Then
clearStuff
aimX = aimX - 1
drawStuff
drawpoint
EndIf

If a = 131 Then
clearStuff
aimX = aimX + 1
drawStuff
drawpoint
EndIf

If a = 32 Then
fireshell
EndIf

For t = 1 To 500:Next t

Loop


End Sub

init

 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 06:47am 12 Oct 2018
Copy link to clipboard 
Print this post

Welcome to the forum.

I don't have a Maximite setup for testing.
KeyDown is not a keyword in the current versions of MMBasic so it is difficult to test on a micromite (the Maximite successor).
It also would depend on the keyboard routines so could not be easily tested using a terminal emulator.

You could try
a = asc(inkey$)

and see if that is usable instead.

Jim

VK7JH
MMedit
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 09:25am 12 Oct 2018
Copy link to clipboard 
Print this post

Hey Joseph - you OK?

A few questions:
I haven't played with the MaxiMite, are you using a PS2 keyboard plugged directly in?
Is KeyDown a Maximite (MMBasic) statement or a Sub you have written?

With scanning a keyboard, if you have access to the hardware then you will be able to check for multiple (and multiple) keys pressed. If you are using a console connection then no such luck. If you hold a key down until it repeats then simultaneously hold another key down, the first input is abandoned in favour of the most recent. You can see this if you open an editor and hold a key down, then hold two keys down etc... thus you'll only ever see a single key with INKEY$

With the hardware in a keyboard, the state of the key up/down is sent by the keyboard controller (which may well be the system cpu) and the driver for it (which is a subsystem in the firmware) maintains a table of all the key number values. This gets updated as key states come in from the keyboard electronics and any tests for key states from (say your program) only ever has to go to the table (you don't actually do this, the system call does). You don't get this with a console connection because you are working through the driver on your PC etc which converts key presses to ASCII values - it is easier for most things to get the actual character of the key you pressed. The driver for the keyboard hides all this tedious state checking and stuff from you so your program can generally get on with the things you want to do... it can get in the way if you don't want that though. I think back to the days of my Amstrad 6128, you had INKEY$ which would fetch the character of he current key in the buffer (or "") and you also had INKEY(n) - note no $ - where n was the key number (in hardware) and the value returned would tell you if that key was up or down. All keys had a hardware number and could be checked - even keys that didn't produce any character - like CTRL and SHIFT. http://www.cpcwiki.eu/index.php/Locomotive_BASIC#INKEY_.28i.29. Some basics e.g. QBasic had an ON KEY(n) GOSUB event that worked by the key number. https://www.qbasic.net/en/reference/qb11/Statement/ON-KEY.htm

So in short - if you have access to the key states coming from the keyboard electronics, you should be able to detect the state of individual keys. If you don't you might be stuck.



Edited by CaptainBoing 2018-10-13
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 10:13am 12 Oct 2018
Copy link to clipboard 
Print this post

Hi Joseph,

some idea (I did not test that):
I would try to replace the SPACE with CTRL keypresses.
(And maybe the CURSOR keys with w-a-s-z or similar if needed)

Please take a look at the MMBasic manual for Maximites Appendix F
Special Keyboard Keys.
  Quote  If the control key is simultaneously pressed then 20 (hex) is added to the code (this is the equivalent of setting
bit 5). If the shift key is simultaneously pressed then 40 (hex) is added to the code (this is the equivalent of
setting bit 6). If both are pressed 60 (hex) is added. For example Control-PageDown will generate A9 (hex).
The shift modifier only works with the function keys F1 to F12; it is ignored for the other keys.


Normaly MMBasic interprets the keypresses as a serial stream. What you need - I think - is somethin more paralell working.

Kind regards
Michael

EDIT: I had to edit for english keyboard layout.
Edited by twofingers 2018-10-13
causality ≠ correlation ≠ coincidence
 
CircuitGizmos

Guru

Joined: 08/09/2011
Location: United States
Posts: 1427
Posted: 04:20pm 12 Oct 2018
Copy link to clipboard 
Print this post

Why not wire in your own buttons? You could use arcade buttons on the Maximite port and test for any combination of left, right, up, down, and fire states.
Micromites and Maximites! - Beginning Maximite
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 08:45pm 12 Oct 2018
Copy link to clipboard 
Print this post

  CaptainBoing said  
Is KeyDown a Maximite (MMBasic) statement or a Sub you have written?

KEYDOWN is a MMBasic function introduced in the Maximite to make game-playing easier. For rapid fire games, it is better than INKEY.

The micromites were not considered a game platform so KEYDOWN was dropped, along with a lot of the graphic functions.

Detecting multiple consecutive key-presses is going to be difficult. Using CTRL instead of SPACEBAR would work, but not when the CTRL/SPACE is the only key pressed.

Having a game-pad with a few buttons wired up would be the most likely way to success.

I am sure that someone would have done that in the past.

Jim
VK7JH
MMedit
 
karjo238
Regular Member

Joined: 12/10/2018
Location: New Zealand
Posts: 60
Posted: 01:14am 14 Oct 2018
Copy link to clipboard 
Print this post

  TassyJim said  

Having a game-pad with a few buttons wired up would be the most likely way to success.

I am sure that someone would have done that in the past.

Jim


Hey guys. Sorry for the delay in replying. Life(TM) gets in the way occasionally.

The gamepad idea, now that you mention it, sounds like a great one. It would help lend an air of authenticity to what I'm trying to do here, so I'll have a hunt around and see what's available here in NZ, and see how difficult it is to hook up to the Maximite.

Many thanks for your help thus far (I'm sure I'll have more questions in the future)

Joseph
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 07:17am 14 Oct 2018
Copy link to clipboard 
Print this post

Hi Joseph,

Welcome to the forum - and great that someone else is needing this feature.

Even though it may not be what you are asking about; the way I overcame the issue (for 'GamePlay') was to use a Nintendo NunChuk. This is an I2C device so is easy to interface to via software, and gives a very nice direction/fire/jump type controller at a low cost.

You can get 'Break-Out-Boards' that have the 6-pin connector shaped into a PCB with 0.1" headers. Google will help you locate availability for you; OR alternatively, you could cut off the end connector, and hard-wire the four relevant wires (two for power, and two for I2C).

Rgds,
WW

 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 11:16am 14 Oct 2018
Copy link to clipboard 
Print this post

There is a Pacman clone (MAXMAN) in the MMBasic Library that maybe can be helpful.

A NunChuk (clone from china at ebay) costs about 3.60 US$.
causality ≠ correlation ≠ coincidence
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025