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

RetroPlayer proof-of-concept #3335

Closed
wants to merge 19 commits into from
Closed

Conversation

garbear
Copy link
Member

@garbear garbear commented Sep 26, 2013

RetroPlayer is a new player core that allows xbmc to play retro arcade games. RetroPlayer is a frontend for libretro (https://github.com/libretro/RetroArch/blob/master/libretro.h), an API created so that the hassle of porting X emulators to Y systems can be consolidated via a single interface (the reference front-end, RetroArch, supports virtually every console and OS, including Android). This PR only includes Linux and Win32 support.

Sorry for the messy spew of bullet points below, I was jotting things down off the top of my head. I'll make this more concise later.

EDIT: Haha this is the ugliest pull request I have ever seen. I promise the code is quite a bit more beautiful than this PR ;)

The PR is broken down as follows:

    1. Temporary [temp] commits: ignore these
    1. Joystick abstraction and XInput support #2370 (Joystick API) abstracts joystick handling, and adds Linux Joystick API and Microsoft XInput support. This PR is a work-in-progress. More work is needed until the API reaches the quality of the Settings API and the Network Manager PR.
    1. Game Info Tags solve the problem of extension clashes with AV files (.bin, .iso, etc). In the future, this will be accomplished by a python-based info loader I wrote named PyRomInfo. ROMs for most platforms contain magic words, which will PyRomInfo can sniff to determine the platform. Most ROMs also include the game title, publisher, unique game ID, etc embedded in the data, which PyRomInfo is able to extract. Game scraper sites, such as http://thegamesdb.net, can use the game ID to return 1:1 matches and avoid fuzzy title-based guesswork.
    1. Game clients - these are libretro emulator binaries. RetroPlayer is capable of directly loading unmodified RetroArch game clients from https://github.com/libretro. The libretro API has serveral limitations. For example, as RetroArch is written in C, there is no context support, so all callbacks must be static functions and thus only 1 game client can be loaded at once. (Also, a call is needed to query the number of controllers, among other things.) Before this is merged, I recommend collaborating on a v2 of the libretro API that addresses these limitations.
    1. RetroPlayer - libretro is essentially some functions for passing rendered 16-bit audio and RGB data to the front-end. Drawing inspiration from DVDPlayer, I wrote a new core to render this AV data in a quasi-similar manner. One thing to note is the single class for both audio and video buffers, which encapsulates the thread-safety, accompanying frame metadata, and memory management in a single class. RetroPlayer provides just-in-time game client installation -- more on this later.
    1. RetroPlayerInput - Handles the input. I broke this out into a separate commit so that the hooks added throughout the code can be easily viewed. See libretro.h for more info on input devices.
    1. Game Add-ons - for now only scripts are supported (I think). As a portion of libretro cores can load files from memory, eventually plugins can provide public domain ROMs (see thread) directly over http.
    1. MyGames window - modeled after MyVideos window, root node contains Game Sources and Game Add-ons. In the future, game library items (platform, title, publisher, player count) will show up under the root node.

Overview/features, in no particular order:

    1. Just-in-time emulator installation. Explanation: you install an emulator (as you do) and play a game. just-in-time reverses this: you hit enter on a game, and if xbmc recognizes an appropriate emulator isn't installed it will download and install one and then launch the game with the newly installed emulator.
    1. ROM compatibility is determined by several factors. Most emulators list extensions and/or supported platforms in their addon.xml. The extension and game info tag platform is screened against these. Some emulators support loading files from memory (VFS), while others require an absolute (possibly local) path and implement their own file input mechanism. Ideally, most emulators should be patched to short-circuit the file loading and support load-from-vfs. Furthermore, some emulators can load ZIPs, yet others that support loading from memory must load the game within the zip when the zip when the zip is "played". The entire loading/compatibility logic is contained within a separate class, GameFileLoader.
    1. Real-time rewind (also known as Braid-style) is supported for some emulators. This works by the emulator reporting a serialized state of the game at each frame. The states are then XORed together for space efficiency, and buffered over 60 seconds. As a result, the user can use the seek bar to rewind an arbitrary number of seconds, or hit the rewind key on the remote to roll back history. In my development branch (not included in this PR) is a save-state manager based on snapshots of these serialized states (includes auto-save functionality). A quick guess, from the OS's resource manager, showed that 60 seconds of a SNES emulator's history (at 60fps) used a little over 100MB of RAM.
    1. Fast-forward is implemented by progressing through frames as fast as possible (my core i7 can do 4x on some emulators). 32x will need a really fast computer. Frame skipping is not supported, nor is it currently possible with the libretro API.
    1. Some emulators require a "system directory" for things like BIOSes, etc. If the emulator asks for a system directory, RetroPlayer will prompt the user on game load. Once set, the system directory can be changed in the emulator's add-on settings.
    1. Libretro allows per-emulator settings, which RetroPlayer hasn't implemented (yet). HACK: Because any emulator can ask for a system directory, I dynamically add this setting in LoadSettings() (so that identical settings.xml files can be avoided for every emulator).
    1. Key maps can be configured by the standard XML process. Because the keyboard X is mapped to a gamepad button, games can be quit using backspace.
    1. Emulator repositories are hosted at https://github.com/garbear/repository.libretro. Linux comes with only 64-bit emus, but the 32-bit repo can be installed from within the add-on manager (requires a restart). I expect this hackjob to go away with binary add-ons.
    1. Loading ROMs can sometimes be a crapshoot. Not all emulators in the repos work (and some segfault under certain conditions). Reports of broken/working emus can be found in the RetroPlayer Subforum.
    1. As a final note, the last refactor might have changes the game client DLL manager. Some emulators are registered twice (harmless), and I received one report on the forum about a NULL game client DLL shared pointer. This might need some inspection.

Much more info and test builds can be found in the RetroPlayer Subforum.

@Memphiz
Copy link
Member

Memphiz commented Sep 27, 2013

Sounds nice! Can you give me a rough idea what would be missing for getting it to fly on osx/ios/android please?

<checksum>https://raw.github.com/garbear/repository.libretro/master/release/linux/addons.xml.md5</checksum>
<datadir zip="true">https://raw.github.com/garbear/repository.libretro/master/release/linux/</datadir>
<hashes>true</hashes>
</extension>

This comment was marked as spam.

@garbear
Copy link
Member Author

garbear commented Sep 27, 2013

@Memphiz SoftAE had horrible 1-second delay, initially "fixed" (with quotations) by hacking in a low-latency mode, and fixed (no quotations) for reals by ActiveAE. Not sure if CoreAE/PulseAE would have the same problem.

I don't recall any other platform-specific areas of the code. It might be as simple as compiling the emulator cores for OSX and popping them in the add-ons folder. only 1 way to find out :)

@ryanroth
Copy link

@Memphiz @garbear the XBMC Xcode project files on OS X need to be updated to include retroplayer if I remember correctly.

@@ -57,6 +62,7 @@
#endif

using namespace ANNOUNCEMENT;
using namespace JOYSTICK;

This comment was marked as spam.

@Memphiz
Copy link
Member

Memphiz commented Sep 27, 2013

@garbear i played around a bit and got mame to build and load the addon. It has "zip" as supported rom extensions. But unfortunatly it only opens the zip file in the browser ... so the mame addon doesn't even start to handle it. Also the "manage emulators" only shows an empty dir ... well what might be missing here?

@Memphiz
Copy link
Member

Memphiz commented Sep 28, 2013

Ok i played with it a bit.

  1. that log output that we don't support the retro_keyboard input method has either to go - or only logged once - it is like a DOS when an emu core uses it (it gets called once for each keyboard key on each frame!)
  2. Audio seems in sync on osx - but i got hickups (but i guess caused by that printout)
  3. All emu cores need to be compiled in our depends system (like done with pvr-addons and binary addons). Else we can't be sure that the binaries can be loaded in xbmc (they need to be compiled with same compiler/sdk combination as xbmc) - this one is a huge problem imo (or needs a huge affort at least)
  4. We need a repo for osx (i tend to do a 32/64 bit shared repo with fat libs - @davilla I do fatlibs for libboblight already....). When installing from zip (as i did for my test) the addons don't get added to the db. When the gamemanager iterates over the game addons to add the supported rom extensions - it only does this for addons in the db. So the extension wasn't added in my case - and the emu wasn't called as a result. I had a hack proposed in the irc backlog
  5. damn those are alot of cores sigh ;)

So i hope you have read my backlog and can take out something from those pasties i threw at you ;)

@garbear
Copy link
Member Author

garbear commented Sep 29, 2013

  1. I'm not sure how to implement the cores that require a RETRO_DEVICE_KEYBOARD device. Instead of tracking keypresses, the keyboard could be polled directly. And if you emulate the backspace, esc and tab buttons, how would the user exit the emulator? The line RetroPlayerInput.cpp#L102 can be commented out in the meantime.
  2. I'm not too familiar with our build systems, so this is something I would need much input on.
  3. The win32/linux/linux32 repos are here: https://github.com/garbear/repository.libretro. The most difficult thing is creating the addon.xmls. The extensions list, etc. are used for just-in-time emulator installation (xbmc has to know the capabilities of remote game clients). I found this info by running the game client and reading the log, or inspecting the source code directly. I suppose we could ask the upstreams (all 20-something repos) if they could maintain an xml like this one. Still, many copy-paste errors were being made on my part, so I created meta.xml files like that one and use a python script to generate the addon.xml files.
  4. I'll find you on IRC at some point

garbear and others added 4 commits September 30, 2013 12:03
…railing slash.

A string is a valid directory with or without a trailing slash. This means we can return either: prefer without, as the occasional game client author tends to concatenate without checking for the trailing slash.
@ghost ghost assigned garbear Oct 17, 2013
Made RETRO_ENFIRONMENT_GET_VARIABLE call only return default value
@garbear garbear closed this Jul 7, 2014
@garbear garbear deleted the retroplayer-pr branch July 7, 2014 00:58
@garbear garbear restored the retroplayer-pr branch July 7, 2014 01:00
@MartijnKaijser MartijnKaijser modified the milestones: Abandoned, obsolete or superseeded, WIP / RFC (code improvements needed) Jul 19, 2014
@garbear garbear deleted the retroplayer-pr branch February 15, 2015 20:23
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

Successfully merging this pull request may close these issues.

None yet

6 participants