JVSCore - Software JVS-Pac for Linux

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • JVSCore - Software JVS-Pac for Linux

      github.com/bobbydilley/JVSCore-Public

      Lots of people where asking on the OpenJVS project for the opposite of what I'd done so this is the first release of my software which will allow you to use a JVS I/O board as a standard input device on Linux.

      This is in very early stages, and currently only supports digital buttons. It'll be updated regularly and I will post here when its done.

      This is an alternative to the JVS-Pac and only requires an RS485 converter, to work. This could be used on a Raspberry Pi for example to play emulators like Mame on a JVS cabinet.

      I'm just posting here now to have a space to release updates, and will make a video / instructions when the software is finalised. I am to support every single function of the JVS I/O spec.
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • Have managed to getting it working with a Type 3 I/O, and have posted a video of it below.

      youtube.com/watch?v=F_d3Dn7Dq5k

      Unfortunately I cannot test the actual functionality as I have no buttons etc. to plug into the I/O at the moment - but hopefully getting the control panel from Let's Go Jungle soon so I'll be able to start work on it properly. The functionality is there to support ALL the input features of JVS so hopefully this will be a very versatile solution!
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • JVSCore now works nicely and is at: github.com/bobbydilley/JVSCore-Public

      It's super easy to compile + install, and making an adapter should take about 5 minutes and cost about £10.

      Supports:

      - Any linux distrobution (probably)
      - Analogue Controls
      - Normal Button Controls
      - Tested on Type 1 and Type 3, should work on anything.
      - Running in the background as a systemd service, which will keep trying to reconnect to any JVS board you plug in.

      I'm open to adding in functionality such as rotary / coin / screen touch position, but at the moment analogue+buttons are enough for my needs. If anyone wants anything specifically added just shout.

      Heres a video of me playing a game with it:

      https://youtu.be/wRQTcAfwV0M

      Please ignore the strange lag with the controls. Mame seems to add in strange dampening effects on analogue joystick and I can't really work out how to turn them off.
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • Awesome work on this project, now the Pi 4 has enough beef to run Naomi games this could be real game changer!

      I've been testing today on Raspbian Buster Lite on a Pi 4 and have run into an issue, not sure if it's the code or my cheap and cheerful Chinese RS-485 adaptor! I can get the code compiled and installed no problem and it runs just fine, however, it only seems to pick up the analog inputs. If I run evtest I can see I only have one device event number available which is zero, it constantly reports back analog input due to the zero settings for fuzz and deadzone so it shows that the Pi and IO are communicating OK. My IO board reports back with the capabilities and says it can support 2 players with digital buttons but it reports either a timeout, a checksum error or Error getting switches. Could it be a timing issue maybe? I'll grab a different type of adaptor, the same as you use in your video, see if that makes a difference.
      Images
      • IMG-20191204-WA0018.jpg

        253.45 kB, 1,599×899, viewed 12 times
      • IMG-20191204-WA0022.jpg

        193.54 kB, 1,599×899, viewed 14 times
      • IMG-20191204-WA0024.jpg

        198.13 kB, 1,599×899, viewed 11 times
    • Hey there!

      You're probably right and I suspect it is something to do with the timing, I get some checksum errors sometimes on mine which i'm not sure how to fix. I think your adapter should be fine though!

      You say you only see one device event number which is zero. This is correct, and that corresponds to that I/O you've got plugged in. You said you get lots of analogue reads reported back, I didn't realise that's what fuzz+deadzone where for, so i'll get that into the next version so hopefully it doesn't display millions of analogue reads all the time. Thanks for the heads up!

      Things to try:

      If you run evdev again, select event zero and then quickly press Ctrl + C it should display what capabilities have been reported to linux, such as switches etc. If you could take a picture of that, I can see how its managing the switches.

      I can see you've manually run `sudo /usr/bin/jvscore`, when you do that, does it remain open forever, or does it error out and close? (btw, when you do run this command make sure you've stopped the service running in the background with `sudo systemctl stop jvscore`, or it'll take over the serial connection)

      From the debugging info it looks like it should be reading the switches fine. For me, because the switches get mapped to the keyboard keys when I press certain switches on my cabinet it will type things into the terminal. Have you tried pressing all the switches on your cabinet, to see if any of them type anything? It's unlikely you'll see the switch reads while theres so much analogue traffic going on, if you type the following command it'll filter out just the switch reads:

      `sudo evtest --grab /dev/input/event0 | grep EV_KEY`


      Hopefully some of these might get us closer to the answer. Thanks so much for testing it out, and any other comments/feedback would be very much welcomed. I'll credit you on the github page for the fuzz+deadzone suggestion.
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • Thanks very much for the speedy response, I managed to test this morning and your filter suggestion worked :) I can see digital inputs appearing when I move the stick and press buttons which is great! I do get double inputs on the stick so I think the debounce setting might need increasing and also I think I only get keypresses for Start and Coin but not the player buttons. I'll double check my cab wiring later just to make sure it's not a physical issue but this is just amazing! Would you mind if I fork your code and have a play around? I've written python based uinput controllers so I can see how the code is working, I'd like to change the inputs to mame defaults too. Also is it possible to add the debounce, fuzz and deadzone settings to the config file?

      Edit: just noticed I'm being an idiot, the evtest shows input pressed, input released, not a double press!

      You can see I tried jstest in the photo attached, I just get a single analog controller with no digital inputs, is that expected? Also, am I right in thinking this section of code is where the button inputs are being defined, using consecutive numbers from input-event-codes.h?

      ioctl(fd, UI_SET_EVBIT, EV_KEY);
      for (int i = 0; i < capabilities.switches * capabilities.players; i++)
      {
      ioctl(fd, UI_SET_KEYBIT, 2 + i);
      }

      Output of evtest:

      Input driver version is 1.0.1
      Input device ID: bus 0x3 vendor 0x8371 product 0x3551 version 0x1
      Input device name: "SEGA ENTERPRISES,LTD.;I/O 838-13683B ;Ver1.07;99/06"
      Supported events:
      Event type 0 (EV_SYN)
      Event type 1 (EV_KEY)
      Event code 2 (KEY_1)
      Event code 3 (KEY_2)
      Event code 4 (KEY_3)
      Event code 5 (KEY_4)
      Event code 6 (KEY_5)
      Event code 7 (KEY_6)
      Event code 8 (KEY_7)
      Event code 9 (KEY_8)
      Event code 10 (KEY_9)
      Event code 11 (KEY_0)
      Event code 12 (KEY_MINUS)
      Event code 13 (KEY_EQUAL)
      Event code 14 (KEY_BACKSPACE)
      Event code 15 (KEY_TAB)
      Event code 16 (KEY_Q)
      Event code 17 (KEY_W)
      Event code 18 (KEY_E)
      Event code 19 (KEY_R)
      Event code 20 (KEY_T)
      Event code 21 (KEY_Y)
      Event code 22 (KEY_U)
      Event code 23 (KEY_I)
      Event type 3 (EV_ABS)
      Event code 0 (ABS_X)
      Value 16
      Min 0
      Max 255
      Event code 1 (ABS_Y)
      Value 16
      Min 0
      Max 255
      Event code 2 (ABS_Z)
      Value 16
      Min 0
      Max 255
      Event code 3 (ABS_RX)
      Value 16
      Min 0
      Max 255
      Event code 4 (ABS_RY)
      Value 16
      Min 0
      Max 255
      Event code 5 (ABS_RZ)
      Value 16
      Min 0
      Max 255
      Event code 6 (ABS_THROTTLE)
      Value 16
      Min 0
      Max 255
      Event code 7 (ABS_RUDDER)
      Value 16
      Min 0
      Max 255

      I have a suspicion I know what is going on, I've tested all player 1 and 2 inputs plus the service and test buttons, here is the only EV_KEY output:

      pi@raspberrypi:~ $ sudo evtest --grab /dev/input/event0 | grep EV_KEY
      Event type 1 (EV_KEY)
      Event: time 1575569148.450595, type 1 (EV_KEY), code 11 (KEY_0), value 1
      Event: time 1575569148.599926, type 1 (EV_KEY), code 11 (KEY_0), value 0
      Event: time 1575569149.286354, type 1 (EV_KEY), code 10 (KEY_9), value 1
      Event: time 1575569149.375928, type 1 (EV_KEY), code 10 (KEY_9), value 0
      Event: time 1575569151.973548, type 1 (EV_KEY), code 15 (KEY_TAB), value 1
      Event: time 1575569152.092980, type 1 (EV_KEY), code 15 (KEY_TAB), value 0
      Event: time 1575569152.449882, type 1 (EV_KEY), code 13 (KEY_EQUAL), value 1
      Event: time 1575569152.598522, type 1 (EV_KEY), code 13 (KEY_EQUAL), value 0
      Event: time 1575569152.895723, type 1 (EV_KEY), code 14 (KEY_BACKSPACE), value 1
      Event: time 1575569153.014678, type 1 (EV_KEY), code 14 (KEY_BACKSPACE), value 0
      Event: time 1575569153.252335, type 1 (EV_KEY), code 12 (KEY_MINUS), value 1
      Event: time 1575569153.341406, type 1 (EV_KEY), code 12 (KEY_MINUS), value 0
      Event: time 1575569155.243712, type 1 (EV_KEY), code 17 (KEY_W), value 1
      Event: time 1575569155.332949, type 1 (EV_KEY), code 17 (KEY_W), value 0
      Event: time 1575569172.043873, type 1 (EV_KEY), code 9 (KEY_8), value 1
      Event: time 1575569172.402207, type 1 (EV_KEY), code 9 (KEY_8), value 0
      Event: time 1575569173.297450, type 1 (EV_KEY), code 16 (KEY_Q), value 1
      Event: time 1575569173.566187, type 1 (EV_KEY), code 16 (KEY_Q), value 0

      As you can see all codes from 17->9 are reported which is the second byte of input data of 4 but the others are ignored - if I've read this bit of code right:

      for (int i = 0; i < 2 * capabilities.players; i++)
      {
      for (int j = 7; 0 <= j; j--)
      {
      emit(fd, EV_KEY, 2 + ( i * 8 ) + j, ( switches[ i ] >> j ) & 0x01);
      }
      }

      I'll keep testing and let you know if I manage to suss where the issue lies
      Images
      • IMG-20191205-WA0000.jpg

        158.94 kB, 1,599×1,200, viewed 12 times
      • IMG-20191205-WA0001.jpg

        256.1 kB, 1,599×1,200, viewed 9 times
      • IMG-20191205-WA0002.jpg

        257.98 kB, 1,599×1,200, viewed 8 times

      The post was edited 7 times, last by chunksin ().

    • Hey again!

      Thanks for all the debugging work - you're probably right, that code probably only uses the first byte. I've only got a Let's Go Jungle setup to run it on which doesn't include many buttons.

      I suspect `jstest` only looks for buttons from a joystick. I've mapped all the switches to keyboard keys, and jstest probably doesn't test for those. I'd be more than happy to switch them up to some proper joystick buttons in the code, and you mention that you know what the defaults for mame are which would help.

      It should be easy enough to create an array of which keys are defined in which order, and then still use a loop to reference them.

      For example: `int keysToMap[] = {BTN_A, BTN_0, BTN_B, BTN_9...}` etc.

      Please feel free to fork, and i'll merge back in if you make any progress. I'll have a little look tonight if I've got time to see what might be going on.

      I'll definately add the fuzz/deadzone values to the config file. Do you think we'll need individual values for each analogue channel, or will one global value suffice?


      ----

      Just had a look at the code in the section you sent:


      It goes from i = 0 to 2 * capabilities.players.

      I think it should go from i = 0 to switchBytes * capabilities.players.

      Think I just missed it when I was refactoring - give that a go and tell me if that open up all the buttons for you!
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2

      The post was edited 2 times, last by bobbydilley ().

    • Thanks for the support with this :)

      I've updated that variable but I think it still gives the same end result, the switchbytes are still 2 based on the calculation 11/8 quot=1 rem=1. In the jvs.c code is the switchbytes variable updated to reflect the number of players? I can't quite work out the logic!

      Edit: so it looks like maybe it's only pulling back 2 bytes instead of 4, do we need to multiply switchbytes by capabilities.players before GetSwitches?
    • Yeah I see what you mean. 1 Players worth of 11 buttons would be 2 bytes, and we're timing that by the amount of players so its correctly trying to read through 4 bytes of data.

      the getSwitches(char *switches, int players, int bytes) function looks to be correctly called with 2 players, and 2 bytes each. So I'm not really sure what its not doing.

      Something to try:

      Right under the emit function call put: printf("%d ", (switches >> j) & 0x01);
      At the end of the outer loop (the one that deals with i) put a printf("\n"); to make it go down to a new line.
      If you want at the end of the inner loop (the one that deals with j) put a printf(" : "); and that will help to seperate each byte of data.

      You should then get an output of 24 0/1s which will better help you see which keys aren't working. I'm assuming one of the bytes will be completely zero and we can work out which one isn't working properly.
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • Ok I tested and am now getting a stream of 4 blocks of 8 bits. Comparing the button key outputs to the byte readout I can see that the data is all there in the byte stream but not in the outputs, only the first 2 bytes worth. Player 1 button 3 is on the third byte and gives you a 1 in the byte stream (first bit of byte 3) but no key output. The player 2 outputs are on the fourth byte but again, no key output. Interestingly player 2 button 3 must be on a fifth byte that's not being read at all! I'll upload a YouTube vid to better explain.

      YouTube Video

      So possibly an issue with the emit command? All the data seems to be there

      The post was edited 1 time, last by chunksin ().

    • Thanks for the vid!

      The system buttons are clearly a problem, and I think you're right I need to be reading in an extra byte for each one.

      I've created a branch called Develop, and i'll be adding that change to there shortly. It's nice to know that the program is getting the data correctly, and it's just the way I'm sending it out. Should hopefully be an easy fix!

      RE the coin, are you testing it by putting a coin in the slot, or do you have a button that simulates that? Unforunately the 'coin' part of JVS is a bit more complex than just a button, and it actually has various functions for increment+decrement coins which i've not yet implemented. You'll probably have to use the service button to coin up for now, and then i'll attempt to get some coin action going once we've got this fixed.

      -- Edit

      Have pushed the code to add the 8 extra button at the start.

      That should mean that 5 sets of 8 come out now, so would be good if you could check if all the buttons at least report for each side. Next is to find out why it's not reporting all of them properly to linux.

      -- Edit Again

      Just found a bug that could have been the problem. I told linux that we've got capabilities.switches * capabilities.players. This means that if we've got 11 buttons and 2 players, we output we've got 22 possible buttons.

      When we read the bytes in, for 11 switches we would read (2*8) 16 bits. This means we loose report out an extra 5 switches that don't exist which push up the remaining ones. So we'd be reporting the spaces for 32 bits (just for the original swtiches), when 10 of those don't actually exist. Have just pushed to the develop branch, and i'm hoping this will fix all your problems :D
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2

      The post was edited 2 times, last by bobbydilley ().

    • Sorry I've been editing the previous message so the threads have possibly got crossed.

      I've you look at the branch 'Develop' i've made all the changes I think are required to fix everything.

      github.com/bobbydilley/JVSCore-Public/tree/Develop

      On your raspberry pi, if you type in:

      `git checkout Develop`

      It'll move you onto the Develop branch, and you can re-compile and install the software, and see if that fixes anything. It's now got fuzz defined in the config file as well, so if you don't want to see the analogue inputs in evtest, you can turn that up really high.
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • OK, I compiled and ran the code, it's now reporting back 12 bytes (boxed in red) and the missing player 2 button 3 is now there and working, oddly, the following byte has inputs stuck on - not sure what these are!

      In terms of the evtest, I now don't get the test button, up, down or the player 1 start button outputting a key so less than before I'm afraid ...
      Images
      • bytestream.jpg

        29.12 kB, 508×517, viewed 7 times
    • Ohh! Sorry made loads of silly mistakes there, have updated the code again on the Develop branch. If you could have another try that would be great!
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2
    • Yesss!! All working apart from player 2 button 3, presumably it disappears off onto the next byte. Fantastic work!

      Edit - confirmed detected properly on the last byte of data but no key output

      Would changing "for (int i = 0; i < switchBytes * capabilities.players + 1; i++)" to "for (int i = 0; i <= switchBytes * capabilities.players + 1; i++)" fix it?

      Edit: No!

      Edit 2: But changing "for (int i = 0; i < (8 * switchBytes) * capabilities.players + 1; i++)" to "for (int i = 0; i < (8 * switchBytes) * capabilities.players + 8; i++)" has fixed it! all working!!

      Many thanks again! :)

      The post was edited 3 times, last by chunksin ().

    • You should get 5 bytes now, with the service+test at the top, 2 bytes for p1 and 2 bytes for p2.

      Don't really know why P2B3 wouldn't work? Does it come up in the list if you add the print statements?
      OpenJVS | OpenLSA | Arcade Blog

      Own: Naomi / Chihiro Type 1 / Chihiro Type 3 / System SP / Lindbergh x 2 / Galeco Power 3D / System 246 Rack C
      Want: Time Crisis 1, Time Crisis 2, The House Of The Dead 1, The House Of The Dead 2