Skip to content

Commit

Permalink
sni: new RessetToMenu method; usb2snes: implement Menu opcode
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesDunne committed Sep 12, 2021
1 parent 6f01a48 commit eba5b79
Show file tree
Hide file tree
Showing 13 changed files with 829 additions and 535 deletions.
1,204 changes: 670 additions & 534 deletions protos/sni/sni.pb.go

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions protos/sni/sni.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ service DeviceControl {
// only available if DeviceCapability ResetSystem is present
rpc ResetSystem(ResetSystemRequest) returns (ResetSystemResponse) {}

// only available if DeviceCapability ResetToMenu is present
rpc ResetToMenu(ResetToMenuRequest) returns (ResetToMenuResponse) {}

// only available if DeviceCapability PauseUnpauseEmulation is present
rpc PauseUnpauseEmulation(PauseEmulationRequest) returns (PauseEmulationResponse) {}

Expand Down Expand Up @@ -95,6 +98,7 @@ enum DeviceCapability {
ResetSystem = 4;
PauseUnpauseEmulation = 5;
PauseToggleEmulation = 6;
ResetToMenu = 7;
// TODO: query ROM name
ReadDirectory = 10;
MakeDirectory = 11;
Expand Down Expand Up @@ -147,6 +151,13 @@ message ResetSystemResponse {
string uri = 1;
}

message ResetToMenuRequest {
string uri = 1;
}
message ResetToMenuResponse {
string uri = 1;
}

message PauseEmulationRequest {
string uri = 1;
// true to pause emulation, false to unpause
Expand Down
38 changes: 38 additions & 0 deletions protos/sni/sni_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions snes/autocloseabledevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ func (a *autoCloseableDevice) ResetSystem(ctx context.Context) (err error) {
return
}

func (a *autoCloseableDevice) ResetToMenu(ctx context.Context) (err error) {
err = a.ensureOpened(ctx, func(ctx context.Context, device Device) (err error) {
err = device.ResetToMenu(ctx)
return
})
return
}

func (a *autoCloseableDevice) PauseUnpause(ctx context.Context, pausedState bool) (ok bool, err error) {
err = a.ensureOpened(ctx, func(ctx context.Context, device Device) (err error) {
ok, err = device.PauseUnpause(ctx, pausedState)
Expand Down
1 change: 1 addition & 0 deletions snes/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

type DeviceControl interface {
ResetSystem(ctx context.Context) error
ResetToMenu(ctx context.Context) error

PauseUnpause(ctx context.Context, pausedState bool) (bool, error)
PauseToggle(ctx context.Context) error
Expand Down
4 changes: 4 additions & 0 deletions snes/drivers/emunw/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ func (c *Client) ResetSystem(ctx context.Context) (err error) {
return
}

func (c *Client) ResetToMenu(ctx context.Context) error {
panic("implement me")
}

func (c *Client) PauseUnpause(ctx context.Context, pausedState bool) (newState bool, err error) {
deadline, ok := ctx.Deadline()
if !ok {
Expand Down
43 changes: 42 additions & 1 deletion snes/drivers/fxpakpro/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ func (d *Device) ResetSystem(ctx context.Context) (err error) {
sb := make([]byte, 512)
sb[0], sb[1], sb[2], sb[3] = byte('U'), byte('S'), byte('B'), byte('A')
sb[4] = byte(OpRESET)
sb[5] = byte(SpaceFILE)
sb[5] = byte(SpaceSNES)
sb[6] = byte(FlagNONE)

if shouldLock(ctx) {
Expand Down Expand Up @@ -46,6 +46,47 @@ func (d *Device) ResetSystem(ctx context.Context) (err error) {
return
}

func (d *Device) ResetToMenu(ctx context.Context) (err error) {
sb := make([]byte, 512)
sb[0], sb[1], sb[2], sb[3] = byte('U'), byte('S'), byte('B'), byte('A')
sb[4] = byte(OpMENU_RESET)
sb[5] = byte(SpaceSNES)
sb[6] = byte(FlagNONE)

if shouldLock(ctx) {
defer d.lock.Unlock()
d.lock.Lock()
}

err = sendSerial(d.f, 512, sb)
if err != nil {
err = d.FatalError(err)
_ = d.Close()
return
}

err = recvSerial(ctx, d.f, sb, 512)
if err != nil {
err = d.FatalError(err)
_ = d.Close()
return
}

if sb[0] != 'U' || sb[1] != 'S' || sb[2] != 'B' || sb[3] != 'A' {
_ = d.Close()
err = fmt.Errorf("menu_reset: fxpakpro response packet does not contain USBA header")
err = d.FatalError(err)
return
}
if ec := sb[5]; ec != 0 {
err = fmt.Errorf("menu_reset: %w", fxpakproError(ec))
err = d.NonFatalError(err)
return
}

return
}

func (d *Device) PauseUnpause(ctx context.Context, pausedState bool) (bool, error) {
panic("implement me")
}
Expand Down
1 change: 1 addition & 0 deletions snes/drivers/fxpakpro/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ var driverCapabilities = []sni.DeviceCapability{
sni.DeviceCapability_ReadMemory,
sni.DeviceCapability_WriteMemory,
sni.DeviceCapability_ResetSystem,
sni.DeviceCapability_ResetToMenu,
sni.DeviceCapability_ExecuteASM,
// filesystem:
sni.DeviceCapability_ReadDirectory,
Expand Down
4 changes: 4 additions & 0 deletions snes/drivers/luabridge/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ func (d *Device) ResetSystem(ctx context.Context) (err error) {
return
}

func (d *Device) ResetToMenu(ctx context.Context) error {
panic("implement me")
}

func (d *Device) PauseUnpause(ctx context.Context, pausedState bool) (paused bool, err error) {
deadline, ok := ctx.Deadline()
if !ok {
Expand Down
4 changes: 4 additions & 0 deletions snes/drivers/mock/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (d *Device) ResetSystem(ctx context.Context) error {
panic("implement me")
}

func (d *Device) ResetToMenu(ctx context.Context) error {
panic("implement me")
}

func (d *Device) PauseUnpause(ctx context.Context, pausedState bool) (bool, error) {
panic("implement me")
}
Expand Down
4 changes: 4 additions & 0 deletions snes/drivers/retroarch/raclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,10 @@ func (c *RAClient) ResetSystem(ctx context.Context) (err error) {
return
}

func (c *RAClient) ResetToMenu(ctx context.Context) error {
panic("implement me")
}

func (c *RAClient) PauseUnpause(ctx context.Context, pausedState bool) (bool, error) {
return false, fmt.Errorf("capability unavailable")
}
Expand Down
29 changes: 29 additions & 0 deletions snes/services/grpcimpl/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,35 @@ func (d *DeviceControlService) ResetSystem(gctx context.Context, request *sni.Re
return
}

func (d *DeviceControlService) ResetToMenu(gctx context.Context, request *sni.ResetToMenuRequest) (grsp *sni.ResetToMenuResponse, gerr error) {
uri, err := url.Parse(request.GetUri())
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}

var driver snes.Driver
var device snes.AutoCloseableDevice
driver, device, gerr = snes.DeviceByUri(uri)
if gerr != nil {
return nil, grpcError(gerr)
}

if _, err := driver.HasCapabilities(sni.DeviceCapability_ResetToMenu); err != nil {
return nil, status.Error(codes.Unimplemented, err.Error())
}

gerr = device.ResetToMenu(gctx)
if gerr != nil {
return nil, grpcError(gerr)
}

grsp = &sni.ResetToMenuResponse{
Uri: request.Uri,
}

return
}

func (d *DeviceControlService) PauseUnpauseEmulation(gctx context.Context, request *sni.PauseEmulationRequest) (grsp *sni.PauseEmulationResponse, gerr error) {
uri, err := url.Parse(request.GetUri())
if err != nil {
Expand Down
13 changes: 13 additions & 0 deletions snes/services/usb2snes/usb2snes.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,19 @@ serverLoop:
}
break

case "Menu":
if device == nil {
log.Printf("usb2snes: %s: %s requires Attach first\n", clientName, cmd.Opcode)
break serverLoop
}

err = device.ResetToMenu(context.Background())
if err != nil {
log.Printf("usb2snes: %s: %s error: %s\n", clientName, cmd.Opcode, err)
break serverLoop
}
break

case "Boot":
if device == nil {
log.Printf("usb2snes: %s: %s requires Attach first\n", clientName, cmd.Opcode)
Expand Down

0 comments on commit eba5b79

Please sign in to comment.