Automatic place char. into keyboard buffer?

Blitz3D Forums/Blitz3D Beginners Area/Automatic place char. into keyboard buffer?

Happy Sammy(Posted 2006) [#1]
Hi all,

We could use keydown/keyhit to check if a key is pressed.
If we want to create a automatic run demo and want
blitz3D automatic place char. into keyboard buffer,
how to do this?
(eg. Blitz3D automatically "press" S to start demo.
"press" X to exit, etc., instead of manually pressing
S and X directly)

Any ideas?

Thanks in advance.
Sammy
:)


Stevie G(Posted 2006) [#2]
I think it's a bit overkill trying to put chars into the keyboard buffer without keypresses. Why not simply set a constant to determine whether in demo mode or not.

const Demo = true
StartGame = ( keydown( S_Key ) or Demo )
EndGame = ( keydown( X_Key ) or Demo )

Stevie


Happy Sammy(Posted 2006) [#3]
Hi Stevie G,

Thank you for your reply.
Here is the solution:
http://www.blitzbasic.com/codearcs/codearcs.php?code=1227

Sammy
:)


Stevie G(Posted 2006) [#4]
Using a DLL for something which can be acheived with a simple workaround is OTT if you ask me. Whatever floats your boat though.


Jams(Posted 2006) [#5]
Agreed, it's completely unnecessary, if you're having to manually input data into the keyboard buffer, you probably need to rethink the whole problem and start again from a different angle...


Happy Sammy(Posted 2006) [#6]
Hi Stevie G and Jams,

The virtual key is needed because I DON'T want
to manually input data into the keyboard buffer.
I don't type 'S' and 'X'. Let Blitz3D do it for me.

The function is useful when you run a auto-play demo.
eg. when you enter old doom game and leave it there,
after a while, it will play automatically.

Thanks
Sammy
:)


Jams(Posted 2006) [#7]
That's not what i meant!

Think of it like this.... pressing a key on the keyboard invokes some kind of response in your code (a function or whatever).

Now you want to have that same response without a keypress.... so just call the function!


jfk EO-11110(Posted 2006) [#8]
sometimes it's useful when you want to control an external exe. Like clicking away a welcome message popup etc.


Stevie G(Posted 2006) [#9]

The function is useful when you run a auto-play demo.
eg. when you enter old doom game and leave it there,
after a while, it will play automatically.



I fail to see how this relies on writing virtual keypresses to the keyboard buffer. The doom demo started after a certain period of time ... it's that simple.

I can see the relevance of using this DLL in Jfk's example above as you can not do this without an external library. However, for your usage I have to agree completely with Jams.


Now you want to have that same response without a keypress.... so just call the function!



Stevie


Andy(Posted 2006) [#10]
>The virtual key is needed because I DON'T want
>to manually input data into the keyboard buffer.
>I don't type 'S' and 'X'. Let Blitz3D do it for me.

The virtual key is not needed in that situation. You simply do as Stevie G suggested above.

>The function is useful when you run a auto-play demo.
>eg. when you enter old doom game and leave it there,
>after a while, it will play automatically.

You just use a timer and act on this timer in an IF...THEN structure.

The reason people are all over you, is because you are using a complicated and unnessesary solution instead of a few lines of B3D code.


Andy


jfk EO-11110(Posted 2006) [#11]
I think there are many misunderstandings in this thread. I guess Sammy was talking about a replay mode as seen in certain games.

Replay or demo modes simply emulate keyhits and mouse action by "feeding" their Input Routines alternatively with data when in demo mode instead of user input.

eg:
if replay_mode=0
 mxs#=mousexspeed()/4.0
 turnentity camera,0,mxs#,0
 mxs_array#(c)=mxs#
 c=c+1
else
 mxs#=mxs_array#(c)
 turnentity camera,0,mxs#,0
 c=c+1
endif


In the first case (play mode) the camera rotation is controlled by the mouse, additionally the rotation is stored in an array

In the ELSE case (replay mode) the camera rotation is controlled by the array data, containing previously stored mouse actions.

Every User Action can be stored this way. When recording and replaying, the same constant framerate should be used to keep things simple. If delta timing etc. is used and a constant framerate is not possible, a slightly more complicated solution is required, utilizing realtime sequencing.

Furthermore the usage of random values (Rand and Rnd) can be tricky. In theory they can be used if they are initialized with the same seed everytime, but that's probably only theory :)

For a fixed demomode sequence the array may be saved to a file that is loaded by default.


Jams(Posted 2006) [#12]
Even with your example, there's still no need to shove the data into the keyboard buffer, it's completely unnecessary.

I think it's a symptom of a poorly coded engine... if all your actions lie inside "if Keyhit(blah) then" blocks then this would seem like the obvious solution.

Far better would be to bind keyhits to specific functions, then when you want to simulate a keyhit, just call that function...


Happy Sammy(Posted 2006) [#13]
Hi all,

Thank you for your reply.

If I MANUALLY input data into the program,
I would use "if keyhit(blah) then" blocks for data input.

Sammy
:)


Andy(Posted 2006) [#14]
>If I MANUALLY input data into the program,
>I would use "if keyhit(blah) then" blocks for data input.

You are not understanding what people are saying to you.

There is no difference whether is is MANUAL or AUTOMATIC.
If you have a variable called demo, and you add something like what Stevie G suggested, then you get automatic demo mode without using a DLL.

When you use a dll, you inherit a lot of properties. You become responsible to your customers for the dll and what it does to the customers system.

Programming is not just about making the computer do what you want, but also to do it in a way which is simple and efficient both to you and to the user.

You won't notice the difference now, and you propably don't understand why people are all over you for this, but using a DLL for something which can easilly be achieved with a few lines of code is silly, inefficient and a waste of your time.

If you don't understand how to do the same in B3D without using a DLL, then just ask. I'm sure everyone here would be more than helpful in that case.

Simple beats complex almost every time.

I applaud your effort to learn B3D.


Andy


Happy Sammy(Posted 2006) [#15]
Hi all,

Thank you for your reply and patience.

Assuming the following configuration:
W - move forward
A - move left
S - move backward
D - move right

Assuming you want your player to move in this way..
WWASSSDWWWWWWWWWWAAWWWWAAAASSWWDDD.... (2000 keystrokes)
(forward, forward, left, backward, backward, backward, right, forward,...)

This keystrokes are saved in a file.
The pseduo code should be something like this:

while not end of file
reading a char. into letter$
select letter$
case "W"
; codes for moving forward
case "A"
; codes for moving left
case "S"
; codes for moving backward
case "D"
; codes for moving right
end select
wend

Later, you change your mind, you want this:
SWSDDSSDASSSSSSSSSSDDDSSSWWWSSDDD........ (2000 keystrokes)
(backward, forward, backward, right, right, ...)

With virtual key, you do NOT need to change a
single line of code. You just change the file content
with keystrokes, then ok.
It seems that with other method mentioned,
I have to change large amount of codes to do
the same thing.

This is how I understand the use of virtual key.

Thanks in advance.
Sammy
:)


Matty(Posted 2006) [#16]
No you don't have to change the code at all. All you have to change is the file.

In my Blood and Plunder Gauntlet Clone for the replay I did as the others have suggested:

In 'record' mode store each action/button press in a 'type', at the end of the session save the data out to a file. Then when in demo mode it would read in the data into a 'type' then act on those actions in sequence during the demo.

No code needs to be changed. You will have to change the data file's contents regardless of whether you use virtual key or generate the data file by playing the game yourself or simply changing them in a text file.


Happy Sammy(Posted 2006) [#17]
Hi all,

In that case, what is the use of virtual key?
I am confused??!!

Sammy
:)


Jams(Posted 2006) [#18]
There is no use in this situation, that's what we've been trying to tell you...

Please study this example:

If DemoMode = True
    Command$ = ReadCommandFromFile() ;Get the next command
    PushKeyboardBuffer( Command$ ) ;Put data into the keyboard buffer
Endif

If KeyDown( KEY_UP )
        Player\Y = Player\Y -1
Endif
...


A much better way to do it would be like this:

If DemoMode = True
    Command$ = ReadCommandFromFile() ;Get the next command.
    Select Command$
        Case "KEY_UP" : PlayerMoveUp() ;Interpret command.
        ...
    End Select
else
    If KeyDown( KEY_UP )
        PlayerMoveUp() ;interpret command.
    Endif
    ...
endif

Function PlayerMoveUp()
        Player\Y = Player\Y -1
End Function
...


Another problem you'll run into if you want to use the keyboard buffer to automate the demo, is that the user can still press keys on the keyboard, and they'll still get put in the buffer along with all your data.


jfk EO-11110(Posted 2006) [#19]
Jams you forgot to say what function "pushkeybordbuffer()" does, and the first

If KeyDown( KEY_UP )
Player\Y = Player\Y -1
Endif

doesn't make sense since you have that function "PlayerMoveUp" unless I misunderstood something.

However, it may be most simple if you add a second valid condition like

if ((keydown(Key_UP)) and (demo=0))   or   ((k(c)=KEY_UP) and (demo=1))

where k(c) is a value taken from a file or array.

Plus: I totally agree, with your second point. Also consider that keydown cannot be replaced by "inserted virtual keyhits" and keydown allows multiple keys to be pressed simultanously.


Jams(Posted 2006) [#20]
Oops, should have mentioned that 2 codeboxes are completely seperate. <Edited :)


Happy Sammy(Posted 2006) [#21]
Hi all,

Thanks a lot.
If I have more questions, I would post again.

Sammy
:)