giongto35 / cloud-game

Web-based Cloud Gaming service for Retro Game
https://www.youtube.com/watch?v=GUBrJGAxZZg
Apache License 2.0
2.3k stars 347 forks source link

Add my own games #151

Closed Scatmannn closed 4 years ago

Scatmannn commented 4 years ago

Hello!

First of all, congratulations for the great work. I really liked it and found it very interesting!

I followed the description of how to build the application and it worked, with the 3 initial games working correctly.

So I tried to add my own snes games by adding the .smc file to the / assets / games / directory but the application doesn't recognize the file and still only displays the 3 by default.

How do I add games from other platforms?

Thanks for listening.

best regards

sergystepanov commented 4 years ago

Hey, @Scatmannn!

I agree, @giongto35 is a legend, who've made this cool project possible. And speaking about your issue, maybe, I could help you.

While it's just enough to place one of the currently allowed SNES ROM files (smc, sfc, swc, fig, bs (I wonder what it stands for (:) into the assets/games folder and restart the app (overworker) in order to load your games, it's possible that ROM filename can't be read by the loader or this ROM is broken. Currently, there is no way to see what's going on during loader loading because there is no trace logging for that, except hard crashes, or is there, @giongto35? Anyways, I've successfully loaded my own SNES ROMs without an issue on the latest app snapshot, so, @Scatmannn, it'd be great if you could provide the exact file names of your ROMs (to find and load them) or just post a downloadable archive with them somewhere. That'd be much easier, I guess.

How do I add games from other platforms?

Right now, it's kinda tricky. There is a config file where you specify libretro cores and available ROM file extensions for folder autoscan:

var FileTypeToEmulator = map[string]string{
    "gba": "gba",
    "gbc": "gba",
    "cue": "pcsx",
    "zip": "mame",
    "nes": "nes",
    "smc": "snes",
    "sfc": "snes",
    "swc": "snes",
    "fig": "snes",
    "bs":  "snes",
       // here you can map file extensions to cores: "file extension" : "libretro core"
       // map any number of (unique among all the cores) file extensions to a core (e.g., "snes" mapping above)
}
...

var EmulatorConfig = map[string]EmulatorMeta {

// and here you can define any number of libretro cores which names are used up above
// don't forget to put a real libretro core library into the `assets/emulator/libretro/cores/` folder
// with the proper for your OS extension (or just all of them): 
.so -- Linux, 
.dylib -- MacOS, 
.dll -- Windows (:
// you can download them here https://buildbot.libretro.com/nightly/
// set 0 to Width and Height and just add a proper Path
// and then you should rebuild the app before starting it

    "gba": {
        Path:   "assets/emulator/libretro/cores/mgba_libretro",
        Width:  240,
        Height: 160,
    },
    "pcsx": {
        Path:   "assets/emulator/libretro/cores/pcsx_rearmed_libretro",
        Width:  350,
        Height: 240,
    },
    "nes": {
        Path:   "assets/emulator/libretro/cores/nestopia_libretro",
        Width:  256,
        Height: 240,
    },
    "snes": {
        Path:   "assets/emulator/libretro/cores/mednafen_snes_libretro",
        Width:  256,
        Height: 224,
    },
    "mame": {
        Path:   "assets/emulator/libretro/cores/mame2016_libretro",
        Width:  0,
        Height: 0,
    },
}
Scatmannn commented 4 years ago

@sergystepanov , thank you so much for your help.

I restarted the application process and was able to list and show my snes roms in the application.

Now the following problem has occurred: When starting any snes game and press any buttom (START, SELECT, ETC), the app simply breaks and freezes. I tried with many different roms and games.

Strange that the ones from NES work perfectly, only the ones that break the app.

I used the game Contra III - The Alien Wars (U) [!]. Smc

This is my error log:

> I0113 15:18:12.595507    2832 log.go:301] Overlord: Received start request from a browser
> I0113 15:18:12.595546    2832 log.go:301] Overlord: Relay start request from a browser to worker
> I0113 15:18:12.596011    2833 log.go:301] Received a start request from overlord
> I0113 15:18:12.596180    2833 log.go:301] Starting game Contra III - The Alien Wars (U) [!]
> I0113 15:18:12.596383    2833 log.go:301] Got Room from local    ID:  
> I0113 15:18:12.596507    2833 log.go:301] Init new room:  514e1003ee5b19ef___Contra III - The Alien Wars (U) [!] Contra III - The Alien Wars (U) [!] {Contra III - The Alien Wars (U) [!] assets/games/Contra III - The Alien Wars (U) [!].smc smc}
> I0113 15:18:12.596608    2833 log.go:301] Updated player Index to:  0
> I0113 15:18:12.597791    2833 log.go:301] Is PC in room false
> I0113 15:18:12.597945    2833 log.go:301] Detach peerconnection
> I0113 15:18:12.598409    2832 log.go:295] Overlord: Received registerRoom room 514e1003ee5b19ef___Contra III - The Alien Wars (U) [!] from worker edcd5b17-7786-49e0-8d75-14a29afc383d
> I0113 15:18:12.598490    2832 log.go:295] Overlord: Current room list is: map[514e1003ee5b19ef___Contra III - The Alien Wars (U) [!]:edcd5b17-7786-49e0-8d75-14a29afc383d]
> I0113 15:18:12.598555    2832 log.go:301] Received room response from browser:  514e1003ee5b19ef___Contra III - The Alien Wars (U) [!]
> I0113 15:18:12.621099    2833 log.go:301] Check  /root/.cr/save/514e1003ee5b19ef___Contra III - The Alien Wars (U) [!].dat  on online storage :  false
> I0113 15:18:12.621129    2833 log.go:301] Check if game is on cloud storage
> I0113 15:18:12.632927    2833 log.go:295] Room 514e1003ee5b19ef___Contra III - The Alien Wars (U) [!] started. GamePath: assets/games/Contra III - The Alien Wars (U) [!].smc, GameName: Contra III - The Alien Wars (U) [!]
> Libretro API version: 1
> ROM size: 1048576
>   library_name: Mednafen bSNES
>   library_version: v0.9.26 c40d159
>   valid_extensions: smc|fig|bs|st|sfc
>   need_fullpath: true
>   block_extract: false
> Video pixel: {0 0 0 1 0 4} 1 0 1 2[Log]: Loading assets/games/Contra III - The Alien Wars (U) [!].smc...
> 
> [Log]:  Using module: snes(Super Nintendo Entertainment System/Super Famicom)
> 
> 
> [Log]: MDFN_MakeFName: ./Contra III - The Alien Wars (U) [!].srm
> [Log]: MDFN_MakeFName: ./Contra III - The Alien Wars (U) [!].rtc
> [Log]: (null)
> -----------------------------------
> --- System audio and video info ---
> -----------------------------------
>   Aspect ratio:  1.3333333730697632
>   Base width:  256
>   Base height:  224
>   Max width:  512
>   Max height:  512
>   Sample rate:  44100
>   FPS:  60.1
> -----------------------------------
> I0113 15:18:12.746981    2833 log.go:295] Viewport custom size is disabled, base size will be used instead 256x224
> I0113 15:18:12.747271    2833 log.go:301] meta:  {assets/emulator/libretro/cores/mednafen_snes_libretro 256 224 44100 60 256 224 1.3333333730697632}
> I0113 15:18:12.747401    2833 log.go:301] Video Encoder:  VP8
> I0113 15:18:12.747533    2833 log.go:301] Enter fan audio
> 0.726540, 0.727273
> listening audio channel true
> panic: runtime error: index out of range
> 
> goroutine 76 [running]:
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch.coreInputState(0x100000004, 0x0, 0xdde0a8)
>   /home/ellus/Downloads/aff/aff/pkg/emulator/libretro/nanoarch/nanoarch.go:146 +0x1df
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch._cgoexpwrap_8b53d38a9b3f_coreInputState(0x100000004, 0x0, 0x0)
>   _cgo_gotypes.go:499 +0x41
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch._Cfunc_bridge_retro_run(0x7f0e516e63f0)
>   _cgo_gotypes.go:276 +0x41
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch.nanoarchRun.func1(0x7f0e516e63f0)
>   /home/ellus/Downloads/aff/aff/pkg/emulator/libretro/nanoarch/nanoarch.go:439 +0x56
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch.nanoarchRun()
>   /home/ellus/Downloads/aff/aff/pkg/emulator/libretro/nanoarch/nanoarch.go:439 +0x2d
> github.com/giongto35/cloud-game/pkg/emulator/libretro/nanoarch.(*naEmulator).Start(0xc000336000)
>   /home/ellus/Downloads/aff/aff/pkg/emulator/libretro/nanoarch/naemulator.go:160 +0x81
> github.com/giongto35/cloud-game/pkg/worker/room.NewRoom.func1(0xc000162480, 0xc00007c360, 0x2260, 0x7ffda194a727, 0xe, 0x1, 0x0, 0x140, 0xf0, 0xda3038, ...)
>   /home/ellus/Downloads/aff/aff/pkg/worker/room/room.go:134 +0x8c6
> created by github.com/giongto35/cloud-game/pkg/worker/room.NewRoom
>   /home/ellus/Downloads/aff/aff/pkg/worker/room/room.go:89 +0x42e
> I0113 15:18:17.057696    2832 log.go:301] [!] read: websocket: close 1006 (abnormal closure): unexpected EOF
> I0113 15:18:17.057728    2832 log.go:301] Unregister server from overlord
> Makefile:75: recipe for target 'dev.run' failed
> make: *** [dev.run] Error 2
> root@ellus-370E4K:/home/ellus/Downloads/aff/aff#
sergystepanov commented 4 years ago

@Scatmannn, yes, I see. I have the same error. Thanks for report, I'll try to look into it tomorrow if @giongto35 won't fix it before me. I haven't look into the code in a while, so I'm not up to date with all the changes. It seems, something has broken in the user input...

giongto35 commented 4 years ago

Thanks @Scatmannn for your interest in the project, sergy also help me a lot making this project becomes real. Thanks @sergystepanov for your punctual support, long time no see you :D. I just updated some input and add voice chat inside. Seems like it is a broken change. I will take a look at it. In meantime, @Scatmannn you can skip the last commit or 2 commits. reset to this one: https://github.com/giongto35/cloud-game/commit/4b9dc14c1154b50ca2d4dd4f10b64b628ad4d7e8

giongto35 commented 4 years ago

Hi @scatmann, I fixed the issue on master. You can pull it again. The bug is that contra game has more than 5 game ports (5 game players ??), so it caused index out of range. I just set the max port to 8 + do some refactor. image

Scatmannn commented 4 years ago

@giongto35

Wow!! Nice!

In fact the bug was happening to all SNES games, no matter if the rom was E, U or J they were all crashing with this problem.

I did some testing here now, about 15 minutes of testing on the Gradius III game and it worked very well.

I'm doing more tests and anything I'm reporting to you, all right!

Thank you very much for your attention and willingness to help.

Best regards

giongto35 commented 4 years ago

@Scatmannn You re welcome :D. Hope you have good experience with the project. Let me know if you find any room for improvement, I 'm willing to do it.

sergystepanov commented 4 years ago

Hm, If I understand correctly that 'port' thing:

The ascending input port indexes provided by the core in the struct are generally presented by frontends as ascending User # or Player #, such as Player 1, Player 2, Player 3, etc.

So, it's basically the maximum cap of distinct inputs of the core. After looking into the code of some cores (nestopia, bsnes), I'm pretty sure the number of ports available in the frontend callback: func coreInputState(port C.unsigned, ... can only be extracted from the environment variable RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, something like this (don't know the exact Go syntax):

case C.RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS:
  descriptors := (*[1 << 30]C.struct_retro_input_descriptor)(data)
  maxPort := 0
  for _, descriptor := range descriptors {
    // array of descriptions terminated with the null description by the docs
    // descriptor.device can be whatever it can be and not only joy_pad
    if descriptor.description == nil { break } 
    if (some cast) descriptor.port > maxPort { maxPort = thatPort } 
  }
break

And this variable (as example in nestopia) is just some description for frontend developers from core devs (:, which should be true but who knows how they code input callbacks, as example in Nestopia they just hard coded 4 port callback (input_state_cb):

 if (supports_bitmasks)
   {
      int16_t ret[4];
      /* Player 0 needs some extra checks */
      ret[0]              = input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
      ret[1]              = input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
      ret[2]              = input_state_cb(2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
      ret[3]              = input_state_cb(3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
...
     for (unsigned p = 0; p < 4; p++)
      {
         for (unsigned bind = 0; bind < sizeof(bindmap_default) / sizeof(bindmap[0]); bind++)
            input->pad[p].buttons |= input_state_cb(p, RETRO_DEVICE_JOYPAD, 0, bindmap[bind].retro) ? bindmap[bind].nes : 0;

Personally, I'd try to connect these things to keep them in sync. In the bsnes, as you said, 5 ports. It's up to core devs to decide how many ports they want (:.

Speaking of this issue, I'd fix this like that:

func coreInputState(port C.unsigned, device C.unsigned, index C.unsigned, id C.unsigned) C.int16_t {
    if id >= 255 || index > 0 || device != C.RETRO_DEVICE_JOYPAD 
                     ->   || port > maxPort in your bitmap struct (:
        return 0
    }

(I'm busy with stuff, probably gonna have some time to code what I wanted by the spring :)

Scatmannn commented 4 years ago

Hello again! @giongto35 @sergystepanov

Today I have done several tests with various games and all are presenting the same problem: Freeze for no apparent reason, even in tests where I simply turn on the game and let it run without pressing any button on the interface or keyboard.

Games tested:

And many others.

If relevant, here is what happens in my log (I use ubunto 18.04 - 64bits for the tests):

> Log:  Using module: snes(Super Nintendo Entertainment System/Super Famicom)
> Log: MDFN_MakeFName: ./Bishoujo Senshi Sailor Moon Super S - Fuwa Fuwa Panic (J).srm
> Log: MDFN_MakeFName: ./Bishoujo Senshi Sailor Moon Super S - Fuwa Fuwa Panic (J).rtc
> Log: (null)
> -----------------------------------
> --- System audio and video info ---
> -----------------------------------
>   Aspect ratio:  1.3333333730697632
>   Base width:  256
>   Base height:  224
>   Max width:  512
>   Max height:  512
>   Sample rate:  44100
>   FPS:  60.1
> -----------------------------------
> I0114 16:25:51.636870    3287 log.go:295] Viewport custom size is disabled, base size will be used instead 256x224
> I0114 16:25:51.637025    3287 log.go:301] meta:  {assets/emulator/libretro/cores/mednafen_snes_libretro 256 224 44100 60 256 224 1.3333333730697632}
> I0114 16:25:51.637091    3287 log.go:301] Video Encoder:  VP8
> I0114 16:25:51.637318    3287 log.go:301] Enter fan audio
> 0.726540, 0.727273
> listening audio channel true
> I0114 16:26:16.488209    3287 log.go:295] ICE Connection State has changed: disconnected
> I0114 16:26:16.488321    3287 log.go:301] ===StopClient===
> I0114 16:26:16.488990    3287 log.go:295] ICE Connection State has changed: closed
> I0114 16:26:16.489114    3287 log.go:301] Data channel closed
> I0114 16:26:16.489154    3287 log.go:301] Closed webrtc
sergystepanov commented 4 years ago

Hi, @Scatmannn! I would like to ask some questions, if you don't mind?

I tried to run (on Windows) your list of games and Gladius (geez, this game is hard) with Pokemon Cards and played for 10 minutes then let them sit for a bit, it worked just fine. Sailor moon with Samurais was just a black screen from the beginning and won't run, same as on RetroArch, so it's a problem with cores themself or these 2 roms. Ok, gonna try to reproduce it on Linux later, then. Hard to tell what problem that can be.

And when you post a wall of text just wrap it into the <pre>text</pre> tags to make it more readable :3

giongto35 commented 4 years ago

Thanks @sergystepanov for the investigation on port :+1:, you always provide valuable insights.

Hi @Scatmannn, As @sergystepanov said, if RetroArch cannot run the game, it's is game issue. I'm also curious about the symptoms: Is it freeze after like 10 mins no input or just stop even at the beginning. I indeed sometimes get hang on production server for some unknown reason, don't know if it's related in this case. I think I rely on WebRTC DataChannel and when it's close for reason like timeout, the game session will stop. I will try to reproduce also.

Scatmannn commented 4 years ago

@sergystepanov , @giongto35: Sorry for bothering you guys too much.

Freezes happen in different ways and happen more often with SNES and PSX. I will try to clearly report my experience:

GAME: Yuu Yuu Hakusho - Tokubetsu Hen (J) .smc

1 - In the first test, it worked for 3 minutes squeezing all inputs normally until lock / freeze.

2 - In the second test, it crashed on the start screen with less than 1 minute.

3 - In the third test it worked for over 5 minutes.

The results are random and the duration too, but occurs with all games on these two platforms (SNES and PSX) with the following log.

I0114 23:11:19.719963    3128 log.go:295] Viewport custom size is disabled, base size will be used instead 256x224
I0114 23:11:19.720074    3128 log.go:301] meta:  {assets/emulator/libretro/cores/mednafen_snes_libretro 256 224 44100 60 256 224 1.3333333730697632}
I0114 23:11:19.720278    3128 log.go:301] Video Encoder:  VP8
I0114 23:11:19.720460    3128 log.go:301] Enter fan audio
0.726540, 0.727273
listening audio channel true
I0114 23:11:48.217795    3128 log.go:295] ICE Connection State has changed: disconnected
I0114 23:11:48.217831    3128 log.go:301] ===StopClient===
I0114 23:11:48.218050    3128 log.go:301] Data channel closed
I0114 23:11:48.218070    3128 log.go:301] Closed webrtc
I0114 23:11:48.218116    3128 log.go:295] ICE Connection State has changed: closed

If you prefer, I can record my screen and put it on youtube to check what happens.

Again, thanks for your attention.

giongto35 commented 4 years ago

hi @Scatmannn ,

Don't worry, I'm really happy to receive feedback. It means you care about the project, so I'm really welcome it. You helped us to detect the breaking change last time as well.

For this freezing issue, I think you are correct. Sometimes I also experienced sudden hang and cannot reproduce it on local. Seems like it 's a common issue and I need to investigate it more seriously.

Scatmannn commented 4 years ago

@giongto35, hello again!

I spent all these days testing and always getting similar results.

it may just be my impression but when I do the direct build, using the commands instead of using the "Run on local by Docker", it seemed to be more consistent, despite continuing to freeze / crash the games.

I also missed the L / L1 and R / R1 buttons for snes and psx.

But in spite of everything, I really liked it and I'm really looking forward to the next version. Great job and congratulations!