timotheeg / nestrischamps

A web-based OCR and restreamer system for NES Classic Tetris players
MIT License
48 stars 12 forks source link

Read game data directly from EverDrive with WebSerial API #159

Closed timotheeg closed 10 months ago

timotheeg commented 10 months ago

Context

The Everdrive N8 Pro has a USB port that can be used to communicate with a NES rom through a FIFO buffer.

@zohassadar has already made a version on tetrisGym to report Game data through that buffer.

This PR is an attempt to use the web SerialPort API to read the frame data from the online client.

Approach

This is already live and ready to be tested. Make sure

  1. you build the correct gym rom that report the data over USB (branch)
  2. Start the rom, start a game and pause
  3. Load NTC's producer page, reset the config, select Everdrive N8 Pro - Direct USB Capture. If nothing appears, refresh and repeat till you see game data.

image

image

Note: Reading game data breaks if you stop the game or go back to the everdrive menus. If you do that, or if generally you just can't get this to work, reset the NES, and repeat step 1 to 3 to get capture working again!

zohassadar commented 10 months ago

One thing I noticed while testing is that requests to the everdrive when the game isn't loaded can cause the everdrive and/or the web app to crash. It looks like there is at least one way to figure out if the game is loaded or not.

When using edlink.exe without any options, information comes back from the everdrive.

When a game is loaded:

mappper.....1 sub.0    
prg size....32K        
chr size....16K        
srm size....8K        
master vol..128        
mirroring...h
cfg bits....00000000  
menu key....0x14      
save key....0x00      
load key....0x00      
save state..yes
ss button...yes
unlock......yes
ctrl bits...10001110
CFG0: 01-62-01-80-00-00-00-8E
CFG1: 14-00-00-00-00-00-00-00

When a game is not loaded:

mappper.....255 sub.0
prg size....8K
chr size....8K
srm size....128B
master vol..0
mirroring...h
cfg bits....00000000
menu key....0x00
save key....0x00
load key....0x00
rst delay...no
save state..no
ss button...no
unlock......yes
ctrl bits...10000000
CFG0: FF-00-00-00-00-00-00-80
CFG1: 00-00-00-00-00-00-00-00

The mapper 255 is unique to the everdrive OS, so that could be used to distinguish between being in game or not. Can also be used to know the everdrive is ready to send a patched rom at that point in development.

It looks like this is what's needed:

CMD_MEM_RD = 0x19 ADDR_CFG = 0x1800000 length = 48

zohassadar commented 10 months ago

https://github.com/zohassadar/nestrischamps/blob/b7e81ffc750759895ecef0183eeac4f11aaa24db/field_mod.py

The javascript is a struggle so i wrote down in python what's happening with the current piece as well as the line clear animation.

timotheeg commented 10 months ago

Considering this works for me, I'm going to merge this for now, and I'll add other things (like detecting in game / in menu, coming up with a frame format v4) later as new PRs.