How to send keyboard commands to emulator?

Asked

Viewed 170 times

3

Eai Galera, I’m trying to make a program to make an automatic combo in a fighting game (The King of Fighters 2002), I’ve tried to use libraries like pyautogui, Keyboard, ctypes and etc, but I can’t get the program to press the keys to automatically walk on the emulator (Fightcade) Can anyone tell me how to fix it? follows what I have code so far:

import pyautogui
import keyboard
import time

def Combo1():
    while True:
        if keyboard.is_pressed('q'):
            pyautogui.keyDown('left')
            time.sleep(0.1)
            pyautogui.keyUp('left')

Combo1()

the bottom is using a windows api to make the commands with direct Keys...

import ctypes
import keyboard
from ctypes import wintypes
import time

user32 = ctypes.WinDLL('user32', use_last_error=True)

INPUT_MOUSE    = 0
INPUT_KEYBOARD = 1
INPUT_HARDWARE = 2

KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP       = 0x0002
KEYEVENTF_UNICODE     = 0x0004
KEYEVENTF_SCANCODE    = 0x0008

MAPVK_VK_TO_VSC = 0

# msdn.microsoft.com/en-us/library/dd375731

Z = 0x2C
X = 0x2D
C = 0x2E
V = 0x2F

LEFT = 0xCB
RIGHT = 0xCD
UP = 0xC8
DOWN = 0xD0

# C struct definitions

SendInput = ctypes.windll.user32.SendInput

# C struct redefinitions 
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]
# Functions
def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def Combo1():
    flag = True
    while True:
        if keyboard.is_pressed('q'):
            while flag: 
                PressKey(DOWN) # 
                time.sleep(0.1)
                ReleaseKey(DOWN) #
                if keyboard.is_pressed('q'):
                    flag = False
            
if __name__ == "__main__":
    Combo1()
  • 1

    It will really depend on how the emulator interacts with the hardware - leave a link pro emulator there - also evaluate if you can play the same game in another emulator.

  • I’m trying to use the Cheat engine to understand the memory addresses responsible for input in the game and then write a script to change these memory addresses any way I want, but it seems more complicated than I thought it would be, I really wanted to make it easier with python, I’ll leave the link of fightcade here if you want to take a look: https://www.fightcade.com/

  • if you are an emulator of an older (16 bit, or cartridge) machine and your emulator has an option to save a "snapshot" - that is - the whole memory of the machine in a single file - a "photo" of the game state - it is more or less quiet to do what you want - but this has nothing to do with sending a sequence of keys to the emulator running.

  • What I want to do with the Cheat Engine is find the memory positions responsible for controlling the game commands, I think it should be a binary 0 or 1 to tell if the key was pressed or something, after that, if I made a script that could change these values and make the commands in the game in a certain order, I could make automatic combos.

  • this is no longer so simple - the pressed key may not even go to memory, depending on the hardware - the CPU checks if a tcla is pressed and calls a direct routine to start a movement - the state that says that the movement is running is the position of the program, and not a memory variable. This type of Cheat works to increase the number of lives, maximize HP, etc..

1 answer

-1

Look for a tool that calls Autohotkey. It allows you to write scripts to capture inputs on the keyboard or mouse and run actions automatically. You can write a script telling you which commands will be sent when you press a certain key. The language for writing scripts is super simple and you can enable/disable each script when using.

For example, see a script I wrote to replace the CTRL + Alt Gr key combination with an arrow on the right when in the Spyder window:

#IfWinActive Spyder (Python 3.8)
LControl & RAlt::
Send, {Right}
return

Browser other questions tagged

You are not signed in. Login or sign up in order to post.