Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up Try the site in https mode Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: MAME source  (Read 1280 times)

0 Members and 1 Guest are viewing this topic.

cpetzol2

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 26
  • Last login:November 26, 2006, 02:25:43 am
MAME source
« on: October 26, 2006, 04:28:06 pm »
Hello,

I am trying to to edit a little something in the MAME source. I have been able to follow most of the code, but there are some things that I just cannot seem to find. I am trying to find something related to the keyboard input to MAME.

This is what I plan to do.  In "UI.C", there is the function "handler_ingame()"which monitors keys that do such things as exit MAME, pause, throttle, single-step forward, adjust volume, and bring up the in-game menu while MAME is emulating a rom. I want to add a function there that checks for an unused key in MAME. This function, in return, will send keystrokes back to the ROM, so the rom thinks they were typed on the keyboard.

After I add another key to check in "handler_ingame()," how do I go about sending keypresses back to the rom. I believe there is a buffer or something, but I cannot find the function that manages it.

I found where the DIRECTINPUT calls are translated into KEYCODES, VKCODES, MAMECODES, and ASCII CODES and then put into a structure called "code", but where does it go from there?
How does the rom get access to it.

When a rom requests to see if a key is pressed, what function does it call, and where is that function?


Let me just ask this, assuming that I have been on the wrong trail, can any point me into some direction as to where I can inject keystrokes into a rom.

Thank you to anybody who can help me out with this. I have read over all of the C files that I think handle this, but I am not a professional programmer by any means, and I believe I am overlooking something. Possibly the functions are right in my face, but the algorithms were a little over my head and I just didnt realize that I was looking at what I needed.

Much appreciated

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:August 14, 2023, 02:00:48 am
  • 0x2b|~0x2b?
Re: MAME source
« Reply #1 on: October 26, 2006, 06:23:51 pm »
Take a look at wininput_poll() in input.c. There is an array called keyboard_state[MAX_KEYBOARDS][MAX_KEYS]; which stores the keys for all keyboards.

To inject a key, say the 5 key into keyboard 0, you would do this:

Code: [Select]
keyboard_state[0][DIK_5] = 0x80;
Simple as that :)

cpetzol2

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 26
  • Last login:November 26, 2006, 02:25:43 am
Re: MAME source
« Reply #2 on: October 26, 2006, 06:25:12 pm »
And I can call that from anywhere, as long as input.c is included?

Also, My cab has an IPAC encoder and a keyboard. The keyboard is plugged into ps/2 and the ipac is usb. Is there a way to know which keyboard is which? Does it really matter which keyboard I inject it into?

Thank you.
« Last Edit: October 26, 2006, 06:29:33 pm by cpetzol2 »

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:August 14, 2023, 02:00:48 am
  • 0x2b|~0x2b?
Re: MAME source
« Reply #3 on: October 26, 2006, 06:37:54 pm »
I would guess so if you have a look at the definition of keyboard_state in windows\input.c you will see it's static. But I would suggest you have your injecting code in the polling function to make sure you can inject the keys. Put it this way, it's reading the keys using Direct Input when calling IDirectInputDevice_GetDeviceState(). Then the "if we couldn't poll the keyboard that way, poll it via GetAsyncKeyState" is a part where they use the GetAsyncKeyState() API function to inject keys manually if Direct Input fails for some reason (keyboard_state[0][dik] = (GetAsyncKeyState(vk) >> 15) & 1;). Setup your own custom injecting routine just after that bit that injects keys you place in your own array

Eg. In your own code declare the following in your header file, then include the header in input.c
Code: [Select]
static BYTE my_keys[MAX_KEYS];
In you code you put the keys you want to inject:
Code: [Select]
my_keys[DIK_5] = 0x80;
my_keys[DIK_1] = 0x80;

Then in the wininput_poll() function in input.c you can then place your my_keys array into the keyboard_state array. Just before the "update the lagged keyboard" line.

Code: [Select]
for(int i=0; i<MAX_KEYS; i++)
    keyboard_state[0][i] = my_keys[i];
« Last Edit: October 26, 2006, 06:40:28 pm by headkaze »

u_rebelscum

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 3633
  • Last login:April 21, 2010, 03:06:26 pm
  • You rebel scum
    • Mame:Analog+
Re: MAME source
« Reply #4 on: October 27, 2006, 01:27:12 pm »
Also, My cab has an IPAC encoder and a keyboard. The keyboard is plugged into ps/2 and the ipac is usb. Is there a way to know which keyboard is which? Does it really matter which keyboard I inject it into?

No, so no.  Well, as far as mame and almost all other windows applications are concerned.  For a application to detect which keyboard it came from, it needs to use RAWinput for reading keyboards.  Mame uses DirectInput or the standard win32 API (headkaze mentions this as "GetAsyncKeyState()" function) for reading the keyboard, as do basically all windows apps.


Also, I'll go a little more into what headkaze said.  He didn't state it outright, but you should inject the keypress into mame's standard input read within mame's Operating System Dependent (OSD) code.  If you try to inject directly to the ROM, you'll have to change every game's driver code that you want whatever you're doing to happen.  I found that once I pictured mame as:

user <--> mame OSD <--> mame core <==> mame game driver <==> ROMs

it was much easier to see what to hack where, plus different possible hacks and which ones looked easier.  (Picture the "==>" as branching to the right.)
Robin
Knowledge is Power

cpetzol2

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 26
  • Last login:November 26, 2006, 02:25:43 am
Re: MAME source
« Reply #5 on: October 27, 2006, 11:26:48 pm »
Im sorry this is lengthy, but any code I have ever written was so much less complicated and organized as the MAME code, I need to make sure I am doing this correctly.

So, I am in the main MAME folder, and go to ui.c. I find handler_ingame(), and set up a fuction that checks for about 5 different keypresses. If it finds one of these presses, it will create a structure that says one of my keys was pressed and then it will say which ones, so the structure will have 6 variables in it.

Then, I want to go into the Windows folder, and find input.c. I find wininput_poll(), and right before the lines

Code: [Select]
// update the lagged keyboard
updatekeyboard();

I will set up such a routine.

Code: [Select]
if(flag_from_handler_ingame)
       switch (key_id)
       {
                case key_1: keyboard_state[0][DIK_ESC] = 0x80;
                case key_2:keyboard_state[0][DIK_MENU] = 0x80;
                case key_3:keyboard_state[0][DIK_1] = 0x80;
                case key_4:keyboard_state[0][DIK_2] = 0x80;
                case key_5:keyboard_state[0][DIK_5] = 0x80;


Is this correct. If more than one of my keys are pressed, can I can keyboard_state[][] twice in a row. Should I use DIK CODES like I did?

Is there a better way to detect certain keypresses rather than adding onto handler_ingame()? Will there be performance issues, such as, handler_ingame only gets called once a second, therefore some keyinjections will be late?

If someone has a little time, and knows of a much more robust way of doing this, or an easier way than what I have above, I would definitly appreciate it. Thank you

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:August 14, 2023, 02:00:48 am
  • 0x2b|~0x2b?
Re: MAME source
« Reply #6 on: October 28, 2006, 04:30:27 am »
First of all you could probably do all this without the need to modify the Mame source at all. Check out the scripting capabilities of AutoHotkey and AutoIt3. You can map any key to any other key or key combination with one line of code, and it will compile your script into an executable if you like. I highly recommend you check these out.

Second like I said in my previous posts IDirectInputDevice_GetDeviceState() or GetAsyncKeyState() is when Mame reads the raw data from the keyboard. So why place your code in handler_ingame(), you can do it all in the wininput_poll() function and then you know all the keys will be processed correctly.

So just before the "update the lagged keyboard" line in windows\input.c\wininput_poll()
Code: [Select]
for (i = 0; i < keyboard_count; i++)
{
    if(keyboard_state[i][DIK_??] & 0x80) { keyboard_state[i][DIK_??] = 0; keyboard_state[0][DIK_ESC] = 0x80; }
    if(keyboard_state[i][DIK_??] & 0x80) { keyboard_state[i][DIK_??] = 0; keyboard_state[0][DIK_MENU] = 0x80; }
    if(keyboard_state[i][DIK_??] & 0x80) { keyboard_state[i][DIK_??] = 0; keyboard_state[0][DIK_1] = 0x80; }
    if(keyboard_state[i][DIK_??] & 0x80) { keyboard_state[i][DIK_??] = 0; keyboard_state[0][DIK_2] = 0x80; }
    if(keyboard_state[i][DIK_??] & 0x80) { keyboard_state[i][DIK_??] = 0; keyboard_state[0][DIK_5] = 0x80; }
}

Obviously replace DIK_?? with the keys you are checking for. This will loop through all keyboards checking for whatever keys you want, then it will clear the keypress if found (important unless you want that key to be processed as well), then set it to key you want into keyboard 0, or you could of course inject it back into the same keyboard i if you wanted to.

But like I said in my first paragraph your going the long way about mapping keys if that's all you want to do.

BTW I noticed in your switch() statement you didn't use a break; after each case, which is not good.
« Last Edit: October 28, 2006, 04:33:40 am by headkaze »