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

Libretro - answers to questions #1

Open
inactive123 opened this issue Jul 12, 2012 · 1 comment
Open

Libretro - answers to questions #1

inactive123 opened this issue Jul 12, 2012 · 1 comment

Comments

@inactive123
Copy link

Hi there,

it's a bit hard to reach you, so since clobber gave me a list of questions pertaining to libretro, I decided it would be best to give a response in an 'issue' - so hopefully you'll forgive me for abusing the 'issues' section for this one time -

[quote]

  • libmame currently doesn't support cheats, so at least for the time being they would be unavailable
    [/quote]

No problem - cheat support in RetroArch is very preliminary and premature too - most of the ports don't have any cheat support implemented and cheat support in RetroArch right now depends on XML dependencies (which are not included for the consle ports).

[quote]

  • libmame currently doesn't support saving emulator state to a data block, so save/restore would be unavailable
    [/quote]

Regrettable but no big deal for now - the libretro port of imame4all doesn't have this implemented right now as well. I understand some games in MAME still don't savestate no matter what - so it's probably very driver-specific.

[quote]

  • libretro doesn't support all of the controller types that MAME needs so until that is changed, some games would be unplayable
    [/quote]

Right now you can target the RetroPad - it's a hypothetical controller that has the button layout of a SNES controller but has the extra buttons and analog sticks from the PS1 Dual Shock controller. This should be more than enough for the vast majority of games one could play in MAME - you can map axis controls to the two analog sticks.

You can also target a mouse if you want - defines for that are in the libretro.h header.

[quote]

  • you are aware that libmame hides all of the MAME UI functionality right? If libretro were implemented more directly to the MAME sources, you could probably lean on the MAME UI for alot of stuff if you wanted to. But I don't know exactly what kind of interface to the emulators libretro is trying to achieve. Is it trying to just control the controller inputs and manage rendering of the video and audio outputs of the emulator, and leave the in-emulator menuing systems in place? Or is it trying to hide all menuing systems (like libmame does) and just provide access to the actual emulation functionality of the emulator?
    [/quote]

There is no real philosophy we follow here, but in general, I feel any GUI that the emulator core itself provides is unneeded - so I dispense with all that - I did the same for the FCEU port. RetroArch basically takes over as far as the entire 'representation' to the user is concerned.

So it's no big deal if we can't pop up the MAME UI menu to reconfigure controls - we could reconfigure them in RetroArch per-game - and in the console ports, it's possible to switch, save and load control presets on-the-fly. Also, ROM loading is all handled by the respective frontends for each port of RetroArch.

[quote]
retro_init/retro_deinit -> whatever I need to do internally
[/quote]

These would be pretty straightforward - retro_init is run before retro_load_game - so anything initialization-wise that you need to handle before you actually load the ROM goes in here.

retro_deinit is for when we want to deinitialize the entire emulator core - on consoles this would be cleaning up the entire state before returning back to the native frontend (on PS3 it would be the XMB, on 360 the dashboard, and so on). A shutdown function in other words.

Note - this function is also called when we load another ROM after the first initial ROM - ie. re-entrant ROM loading.

[quote]
retro_api_version -> not sure, is this supposed to return something libretro-specific or libmame-specific?
[/quote]

You don't need to touch this - this is put there in case we ever have to bump up the API version of libretro and want to check for a specific version in RetroArch. Just copy-paste the contents of what is in every libretro port right now.

[quote]
retro_get_system_info -> not sure, it's not obvious to me what this function is supposed to do
[/quote]

What we do here is set a few specific variables that some of the RetroArch ports depend on.

For instance -

[quote]
info->library_name = "Genesis Plus GX";
info->library_version = "v1.7.0";
info->valid_extensions = "md|smd|bin|cue|gen|zip|MD|SMD|bin|CUE|GEN|ZIP|sms|SMS|gg|GG|sg|SG";
info->block_extract = false;
info->need_fullpath = true;
[/quote]

valid_extensions is a list of all the 'ROM files' that the libretro port supports - the console ports will use this delimited string value to 'filter' the file browser contents against all supported ROM extensions.

block_extract - you will probably have to set this to true for MAME - since MAME handles ZIP loading/extraction internally - normally for any given libretro port, the frontend built for RetroArch can extract a ZIP file first to a cache partition if you feed it - for instance, this is the way things work for the 360/PS3 ports. If block_extract is set to true, this behavior is disabled so the libretro port (MAME) will deal with the ZIP file and the subsequent loading of it itself. This is what you want for MAME.

need_fullpath - some emulators/games need full path filenames - say, for their ROM loading. Set this to true if this is the case.

[quote]
retro_get_system_av_info -> would have to return garbage (zeros) unless called when a game is actually running; when a game is running, would return the game description values that libmame can provide for the running game
[/quote]

You can look at pre-existing examples in any of the libretro ports I've done - a couple of fleshed out ones are SNES9x Next, FCEUmm, VBA Next and so on.

Basically, you set the sampling rate here - the proper FPS and the geometry values. These values are used for ffmpeg recording. Also, the Wii port depends on exact FPS/sampling rate reporting because of the way we handle audio in that port (it's different from the other console ports).

You will definitely need to set meaningful values here or else the emulator /game will not correctly boot up. See the existing example in the imame4all-libretro port -you might be able to borrow some stuff from there.

[quote]
retro_set_xxx -> would just save the callbacks away, just like any other libretro implementation
[/quote]

yes.

[quote]
retro_set_controller_port_device -> I'm guessing this is supposed to tell the emulator what device it should believe is plugged into each possible "port". This would do nothing for libmame which has fixed controllers that cannot be changed (might be more useful when eventually libmame is expanded to include MESS support and is called libume).
[/quote]

Exactly - at the moment we haven't had much use for it either.

[quote]
retro_reset -> would be a no-op if no game is running, or would do LibMame_RunningGame_Schedule_Hard_Reset, which would reset the emulator (but the game that was previously running would just start again since games being run persist in the emulator until another game is run)
[/quote]

This is exactly what we want and what it's there for - to 'reset' the current game that is loaded.

[quote]
retro_run -> if a game is already running, would run one frame of that game by calling the new LibMame_RunningGame_RunOneFrame function (or whatever I decide to call it). If no game is running, would be a no-op.
[/quote]

OK - however, what do you mean by 'if no game is running'? I thought the MAME UI was hidden away, so wouldn't a game always be loaded?

[quote]
retro_serialize_XXX, retro_unserialize -> not supported yet (although I supposed it could be done in a hokey way, but allowing MAME to save the game to a temporary file, then reading that file into the buffer, then deleting the file, and something similar for unserialize)
[/quote]

It's probably not really important for an initial release - so you can no-op it for now (look at Mednafen PCE for examples of how this could work). Note that the serialization approach works by serializing save states. It's there for real-time rewinding and netplay.

[quote]
retro_cheat_XXX -> not supported yet
[/quote]

No problem.

[quote]
retro_load_game -> would call a new LibMame_RunGame_FrameByFrame (or whatever I decide to call it), which would start the game (loading ROMs and what have you) but would stop and return before actually running the first frame of emulation, waiting for retro_run to be called for each successive emulated frame. NOTE that the path in retro_game_info would be expected to be the game name as known to MAME (i.e. pacman for Pac-Man, lastbld2 for Last Blade 2), not a full filesystem path. The rom path and other paths would be provided to the emulator by calls out through retro_environment_t callback with new MAME-specific commands (i.e. GET_ROM_PATH, GET_SAMPLE_PATH, etc). Alternately, the meta field of retro_game_info can be used if it is for what it seems like it is for (passing emulator-specific parameters in).
[/quote]

Sounds good. As for the other system paths you have to set up - the libretro port of Genesis Plus GX does something similar and uses the environment extension 'GET_SYSTEM_DIRECTORY' for that. We're open to new extensions though if they serve an additional purpose.

[quote]
retro_load_game_special -> I have no idea what this is supposed to do. Probably would not be used for libmame.
[/quote]

This function is for specific tasks - it's usually left unimplemented. Say that you were to load a Sufami Turbo game on the Super Nintendo which requires you to load two ROMs, or a Super Game Boy game on bSNES - something along that nature.

[quote]
retro_unload_game -> would call some new function like LibMame_RunningGame_Stop, which would just terminate the emulation and clean up all resources it used
[/quote]

Yes - you need to just clean up your resources here for the current game that is being run.

[quote]
retro_get_region -> not supported
[/quote]

just wing it here and return RETRO_REGION_NTSC - since this is arcade we don't care.

[quote]
retro_get_memory_XXX -> not sure what these are supposed to do, but probably not supported
[/quote]

This is mosty used for SRAM saving and similar saving-related tasks on console emulator ports. You can probably leave this unimplemented for now.

I hope I answered most of your questions sufficiently. If not, please ask some more.

@bji
Copy link
Owner

bji commented Jul 12, 2012

On 07/11/12 19:12, Squarepusher wrote:

Hi there,

it's a bit hard to reach you, so since clobber gave me a list of questions pertaining to libretro, I decided it would be best to give a response in an 'issue' - so hopefully you'll forgive me for abusing the 'issues' section for this one time -

Hi, sorry if I seem hard to reach; mail to bryan@ischo.com should do the
trick.

[quote]

  • libretro doesn't support all of the controller types that MAME needs so until that is changed, some games would be unplayable
    [/quote]

Right now you can target the RetroPad - it's a hypothetical controller that has the button layout of a SNES controller but has the extra buttons and analog sticks from the PS1 Dual Shock controller. This should be more than enough for the vast majority of games one could play in MAME - you can map axis controls to the two analog sticks.

OK, but what is the libretro device type for the analog sticks?
RETRO_DEVICE_ID_LIGHTGUN_XXX seem like the only possible device type, so
is that what I would use to query an analog stick?

Also I could use the MOUSE ones for trackballs and spinners and stuff.

I think it would be helpful to know how each of the controls from your
RetroPad map to { port, device id } in libretro.

[quote]
retro_get_system_info -> not sure, it's not obvious to me what this function is supposed to do
[/quote]

What we do here is set a few specific variables that some of the RetroArch ports depend on.

For instance -

[quote]
info->library_name = "Genesis Plus GX";
info->library_version = "v1.7.0";
info->valid_extensions = "md|smd|bin|cue|gen|zip|MD|SMD|bin|CUE|GEN|ZIP|sms|SMS|gg|GG|sg|SG";
info->block_extract = false;
info->need_fullpath = true;
[/quote]

valid_extensions is a list of all the 'ROM files' that the libretro port supports - the console ports will use this delimited string value to 'filter' the file browser contents against all supported ROM extensions.

block_extract - you will probably have to set this to true for MAME - since MAME handles ZIP loading/extraction internally - normally for any given libretro port, the frontend built for RetroArch can extract a ZIP file first to a cache partition if you feed it - for instance, this is the way things work for the 360/PS3 ports. If block_extract is set to true, this behavior is disabled so the libretro port (MAME) will deal with the ZIP file and the subsequent loading of it itself. This is what you want for MAME.

need_fullpath - some emulators/games need full path filenames - say, for their ROM loading. Set this to true if this is the case.

Ah - I get the feeling that the valid_extensions are used in some kind
of browser for game selection, with files that match the pattern having
their name presented as a "game" that could be played. For libmame, the
.zip files of the ROMs could be used for this, but the resulting names
are not that useful for selecting games as the game identifier (i.e.
lastbld2 for Bakumatsu Romano / Last Blade 2) are not that
user-friendly, and furthermore, some non-game .zip files may be present
such as BIOS files and such. But I guess as a rough approximation of
the available game list, the list of ROM .zip files could work.

[quote]
retro_get_system_av_info -> would have to return garbage (zeros) unless called when a game is actually running; when a game is running, would return the game description values that libmame can provide for the running game
[/quote]

You can look at pre-existing examples in any of the libretro ports I've done - a couple of fleshed out ones are SNES9x Next, FCEUmm, VBA Next and so on.

Basically, you set the sampling rate here - the proper FPS and the geometry values. These values are used for ffmpeg recording. Also, the Wii port depends on exact FPS/sampling rate reporting because of the way we handle audio in that port (it's different from the other console ports).

You will definitely need to set meaningful values here or else the emulator /game will not correctly boot up. See the existing example in the imame4all-libretro port -you might be able to borrow some stuff from there.

I haven't looked at imame4all-libretro but I don't understand how
libmame could sensibly respond to retro_get_system_av_info when a game
is not running (i.e. retro_load_game has been called), since each game
has its own refresh rate and screen resolution and stuff.

Also I thought that this frequency was used by the loop that runs
retro_run() so that the caller could know at exactly what frequency to
call this function to have the game produce audio and video frames at
the original frame rate of the game? I was positive that this is how
the workings of libretro was described to me in an IRC chat.

[quote]
retro_run -> if a game is already running, would run one frame of that game by calling the new LibMame_RunningGame_RunOneFrame function (or whatever I decide to call it). If no game is running, would be a no-op.
[/quote]

OK - however, what do you mean by 'if no game is running'? I thought the MAME UI was hidden away, so wouldn't a game always be loaded?

A game isn't running until retro_load_game is called. If retro_run is
called before that, it's a no-op.

[quote]
retro_load_game -> would call a new LibMame_RunGame_FrameByFrame (or whatever I decide to call it), which would start the game (loading ROMs and what have you) but would stop and return before actually running the first frame of emulation, waiting for retro_run to be called for each successive emulated frame. NOTE that the path in retro_game_info would be expected to be the game name as known to MAME (i.e. pacman for Pac-Man, lastbld2 for Last Blade 2), not a full filesystem path. The rom path and other paths would be provided to the emulator by calls out through retro_environment_t callback with new MAME-specific commands (i.e. GET_ROM_PATH, GET_SAMPLE_PATH, etc). Alternately, the meta field of retro_game_info can be used if it is for what it seems like it is for (passing emulator-specific parameters in).
[/quote]

Sounds good. As for the other system paths you have to set up - the libretro port of Genesis Plus GX does something similar and uses the environment extension 'GET_SYSTEM_DIRECTORY' for that. We're open to new extensions though if they serve an additional purpose.

Hm, I had an idea. I guess that the full path to the ROM .zip file
could be passed in via the path parameter of retro_game_info, and then
libretro could decompose that into a .zip file name and a directory
containing that .zip file, and internally set rompath required by MAME
to that directory and take the game name from the .zip file. In other
words:

retro_game_info.path = "/path/to/my/roms/pacman.zip";

Calling retro_load_game with that retro_game_info would cause
libretro-libmame to:

  • Use /path/to/my/roms as the rompath
  • Use pacman as the game name

Thus there doesn't need to be any environment value or meta value in
retro_game_info to name the rompath.

Thanks,
Bryan

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