Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starting from scratch (no cards, fresh build etc) gives JSON syntax error #3

Open
hjri opened this issue May 21, 2022 · 15 comments
Open

Comments

@hjri
Copy link
Contributor

hjri commented May 21, 2022

Just testing this program with a disconnected serial adapter (i don't have an arcade machine but plan on making some public-arcade-ready solution for someone) and just opening web interface gives an error since /list endpoint returns ] instead of []. Rest of the UI seemingly also breaks as buttons seemingly just refresh page (i.e. submit a form).

built myself on debian linux x86-64

@GXTX
Copy link
Owner

GXTX commented May 21, 2022

Thanks for checking it out!

opening web interface gives an error since /list endpoint returns ] instead of []

I knew this would be an issue, it shouldn't effect functionality but i've fixed it anyway. Let me know if it's fixed for you.

Rest of the UI seemingly also breaks as buttons seemingly just refresh page (i.e. submit a form).

This is as designed, it returns back to the main page after submitting. Currently there is no "api" setup to monitor if and what card is currently inserted, it's planned but very low right now. Similarly the site is designed to show an image of a generated card which is a WIP on the prt branch.

ezgif-4-c86fc4832d

@hjri
Copy link
Contributor Author

hjri commented May 21, 2022

Having an API would be really REALLY nice. Unfortunately I can't really help with the code (as much as I wish I could) since I have zero knowledge in C++, but I might end up reimplementing emulator in JS (node).

My general idea is to make a drop-in replacement for actual WMMT3 machines that uses RFID/NFC/IC cards instead of paper-magnetic ones, while storing card data on a server.

Just so that I can stop bothering arcade owner to turn on the card reader :DDDDD (since it's freeplay)

(and hopefully maybe make F-Zero AX and Mario Kart GP more playable at same time)

@GXTX
Copy link
Owner

GXTX commented May 21, 2022

Having an API would be really REALLY nice. [...] but I might end up reimplementing emulator in JS (node).

What else would you like to see? Card status is planned and is trivial to implement when I have motivation.

(and hopefully maybe make F-Zero AX and Mario Kart GP more playable at same time)

These 2 should be playable as is, but I don't own them to test, as well as iDOLM@STER.

@hjri
Copy link
Contributor Author

hjri commented May 21, 2022

I could potentially test F-Zero and Mario Kart if we manage to get the wiring for it.

What else would you like to see?

I'm not entirely sure how emulator works regarding card write limits or if changing the load status requires machine restart or not but here's some suggestions:

  • Set/unset "dispenser empty" flag so that machine won't ask if player wants a card (most people in arcade play without one and since it's japanese version they don't understand the question (and waste cards if it's left loaded since freeplay means cards are also free)
  • webhook/hup signal to a given PID to indicate that card needs to be taken out (i.e. to signal "card master" controller program that it needs to move card data to a backup or to "reset" the NFC reader)
  • card/emulator status api or webhook/pubsub/websocket
  • api to (re)load card data

My idea of new flow would be:

  1. NFC card reader is used just to read card ID
  2. Card data file is associated with given ID
  3. During normal play emulator reports empty dispenser, preventing game from prompting for new card creation
  4. If NFC card is scanned it requests emulator to set dispenser to "full" and load the given file (creating one if needed)
  5. When virtual card is ejected NFC reader "resets" and tells emulator to unload card and set dispenser to "empty"

Biggest question for me right now - does emulator handle card expiration at all, i.e. does "card data" means actual card dump and after card is "used up" you need to unload it manually and it changes the file automatically as it "dispenses" new card? Or "card data" is a save file and either hacks card use counter or handles expiration process automatically?

@GXTX
Copy link
Owner

GXTX commented May 22, 2022

I think the biggest issue right now is documentation.

Set/unset "dispenser empty"
If NFC card is scanned it requests emulator to set dispenser to "full" and load the given file (creating one if needed)

It's possible to expose this, but I'm not sure how games will handle having the dispenser depleted and filled while running. I guess it would depend per-game how it handles that, and if it doesn't handle it well then you'd need to restart the machine or enter test mode and go back.

webhook/hup signal to a given PID to indicate that card needs to be taken out (i.e. to signal "card master" controller program that it needs to move card data to a backup or to "reset" the NFC reader)
card/emulator status api or webhook/pubsub/websocket

I think I want to avoid over complicating things by adding dependencies to handle sockets, etc. So at most I'd be able to offer more of what's on the site backend with more documentation so you can do what you need to do via http requests.

api to (re)load card data

I'm not quite sure what you mean. Currently the emulator creates 1-3 files on the specified folder being card.bin appended with .track_1 through 3. When the game ejects the card we automatically (can be changed) "grab" the card and tell the game the card it's removed. Once the player wants to reinsert the card, the data is read again from the specified file. There's no cache when there's nothing in the machine.

Biggest question for me right now - does emulator handle card expiration at all, i.e. does "card data" means actual card dump and after card is "used up" you need to unload it manually and it changes the file automatically as it "dispenses" new card? Or "card data" is a save file and either hacks card use counter or handles expiration process automatically?

We don't do any type of hacking on the card data (tho possible depending on game - i've mostly RE'ed the MT2 struct but that's out of scope). When a card is used up it simply ejects the card and writes the expired card data to the fs, then the games themselves will issue the dispense command (as the tray will be empty now) and write the new card data over the expired card.

I could potentially test F-Zero and Mario Kart if we manage to get the wiring for it.

I'd love that.

Wiring:
J3 on Triforce to Female 9-pin D-sub that connects to USB Serial Adapter:
Pin 3 [or 8] (GND) - Pin 5 (GND)
Pin 4 (TXD) - Pin 2 (RXD)
Pin 5 (RXD) - Pin 3 (TXD)

Bridge pin6 (RTS), and 7 (CTS) together on the Triforce side

@hjri
Copy link
Contributor Author

hjri commented May 22, 2022

I think I want to avoid over complicating things by adding dependencies to handle sockets

websockets is probably the easiest/most convenient way of having programmable two-way communication tho. Regular HTTP API is one-way only and to listen for events you'd need to poll it regularly, which might not be something you'd want on an "embedded" kind of system.

and write the new card data over the expired card.

so, basically the expired card is essentially discarded and same save file is used for newly dispensed card? Yeah that seems fine, but it would also be cool to somehow save the expired card data, since they aren't really expired, just at end of their lifespan, and still have at least 5 uses remaining, which WMMT3 uses for "bring a friend" kind of thing: https://wanganmidnight.fandom.com/wiki/Discarded_tuning_card

@hjri
Copy link
Contributor Author

hjri commented May 22, 2022

It's possible to expose this, but I'm not sure how games will handle having the dispenser depleted and filled while running. I guess it would depend per-game how it handles that, and if it doesn't handle it well then you'd need to restart the machine or enter test mode and go back.

Yeah, I don't know either but we could also test that. Potentially real-life solution could wire into machine itself as well to reset. Arcade I'm doing this for has Mario Kart GP (seemingly has card reader but no cards), F-Zero AX (no card reader (only game cube memory card slot), owner tells me cards are practically unobitanium), and Maxi3DX+ we could test how games react to different emulated situations, but we'll need some way to set emulator state in real time, if not websockets then some command prompt could make do.

@GXTX
Copy link
Owner

GXTX commented May 23, 2022

but we'll need some way to set emulator state in real time

This is already possible via http get actions. I've added the ability to change the dispenser status via them as well. For documentation purposes....

http://127.0.0.1/actions?
                  cardname=name.bin
                  insert
                  remove
                  dispenser=true/false
                  list

it would also be cool to somehow save the expired card data

You'd have to keep copies of every write, there's no way to know what one is a expired card unless you work on RE'ing the card structure (and add custom handling, oos).

@hjri
Copy link
Contributor Author

hjri commented May 23, 2022

I've added the ability to change the dispenser status via them as well.

nice!! thank you!

You'd have to keep copies of every write

keeping copies every time would probably be even better tbh.

there's no way to know what one is a expired card

not exactly, it's a bit game specific, but you could just have a timeout/amendment mechanism, i.e.

  1. eject card
  2. if get request for dispensing a new card it means previously ejected one is expired, mark it as such

IIRC Maxi3DX+ will refuse to use card that's about to expire if dispenser is empty.

also, just a thought - since game prints human-readable information on card itself that could be used to determine card status, i.e. it changes "name" segment to some of the predefined strings, i.e. "Disused Card" "プレゼントカード" (present card), it also changes "mileage" and "password" section to instructions, at least for present card.

@hjri
Copy link
Contributor Author

hjri commented Jun 3, 2022

Just tested WMMT3DX+ and F-Zero. Wiring was kinda flimsy (i used jumper wires on the male DB9 connector directly - not very reliable but should work for testing)

Couldn't get ANY response out of WMMT3DX+ no matter how we wired them, just nothing - debug logs never shown anything as if it's not connected. I suspect it miiiight be using different serial protocol or different baud settings (?) or something else entirely. Machine just shown error i think E51 during POST when it got to card reader testing.

F-Zero AX however did get some response - but game refused to start - self test in the menu fails and just straight up booting the game gets card reader error. Here's a dump of things:

[info] Starting API server...
[debug] SerIo::Read:
[debug]  02 06 40 00 00 00 03 45 02 06 40 00 00 00 03 45 02 06
[debug] CardIo::ReceivePacket:
[debug]  40 00 00 00
[debug] SerIo::SendAck: 06
[debug] SerIo::Read:
[debug]  02 06 40 00 00 00 03 45 02 06 40 00 00 00 03 45 02 06 40 00 00 00 03 45
[debug] CardIo::ReceivePacket:
[debug]  40 00 00 00
[debug] SerIo::SendAck: 06
[debug] CardIo::ReceivePacket:
[debug]  40 00 00 00
[debug] SerIo::SendAck: 06
[debug] CardIo::ReceivePacket:
[debug]  40 00 00 00
[debug] SerIo::SendAck: 06

@GXTX
Copy link
Owner

GXTX commented Jun 3, 2022

F-Zero: It doesn't make much sense to me that it we wouldn't reply to a 0x40 (cancel), but it looks like that's what it's expecting or it's not sending the ACK. I've tested it in MT2 and it "works" but causes a delay in moving to the new screen to create a card (it issues this on the page where it asks you if you have a card).

MT3DX+: I'm not sure about this. I know for a fact it works for the TeknoParrot guys during their testing but they don't connect to it via a normal serial connection. If it were only baud rate it should likely produce garbage but you're not seeing that.

I've created a new branch skip_40_b which skips 0x40 and adds a new config.ini value for baud rate.

Edit: Testing on MT3 skipping 0x40 causes the game to lockup. So something very strange is happening with F-Zero.

@GXTX
Copy link
Owner

GXTX commented Jun 3, 2022

    cfgetispeed(&local_50);
    cfgetospeed(&local_50);
    iVar1 = *(int *)(this + 0x14);
    if (iVar1 == 1) {
      in_buad = 0xe;
      out_baud = 0xe;
    }
    else if (iVar1 == 2) {
      in_buad = 0xf;
      out_baud = 0xf;
    }
    else {
      in_buad = 0xd;
      out_baud = 0xd;
      if (iVar1 != 0) {
        return 0;
      }
    }
[...]
    cfsetispeed(&local_50,in_buad);
    cfsetospeed(&local_50,out_baud);

If I follow this correctly it should only be possible for N2 to set 9600, 19200, and 38400 baud on the serial port.

@GXTX
Copy link
Owner

GXTX commented Jun 6, 2022

While chatting with derole we found out that it's 38400b by default for MT3. I've pushed my changes to the main branch. F-Zero I'm still not sure what that could be, perhaps RTS/CTS not being bridged, not sure.

@hjri
Copy link
Contributor Author

hjri commented Jun 7, 2022

Last time we tried f-zero again it didn't work at all so i'm assuming it could easily be wiring issue, after all i'm just sticking female header of a jumper wire into male DB9 socket, it should work but I guess not as reliable, to eliminate wiring issue i'm waiting for a DB9 breakout adapter to arrive, we'll make proper harnesses and stuff, but it'll take time, probably 2 weeks.

Meanwhile I'll try contributing proper API and more debugging logging for the future.

@GXTX
Copy link
Owner

GXTX commented Jun 7, 2022

F-Zero and MT3 are issues with parity. Both appear to use even parity. I've created a new branch that's not ready to be merged as fix/settings_work, this exposes parity via config.ini.

See: https://github.com/GXTX/YACardEmu/tree/fix/settings_work#info

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants