libretro / RetroArch

Cross-platform, sophisticated frontend for the libretro API. Licensed GPLv3.
http://www.libretro.com
GNU General Public License v3.0
10.33k stars 1.84k forks source link

New global init/deinit system for consoles #187

Closed inactive123 closed 10 years ago

inactive123 commented 11 years ago

Still doesn't work out for consoles.

Tried it with this patch -

https://gist.github.com/twinaphex/5434093

It now gets stuck at 'Reading ROM from stdin' before it can even reach the menu - so it just 'hangs' there.

This indicates to me that it is entering here in retroarch.c -

if (!g_extern.libretro_dummy) { fill_pathnames();

  if (!init_rom_file(g_extern.game_type))
     goto error;

  set_savestate_auto_index();

  if (!g_extern.sram_load_disable)
     load_save_files();
  else
     RARCH_LOG("Skipping SRAM load.\n");

  load_auto_state();

ifdef HAVE_BSV_MOVIE

  init_movie();

endif

ifdef HAVE_NETPLAY

  init_netplay();

endif

}

Ie. g_extern.libretro_dummy is 'false' (for whatever reason - I thought --menu would set it to true?) and it tries to load a ROM instead.

Really, I don't think this 'dummy libretro core' approach is working out at all on the consoles where we statically link in the libretro core.

Themaister commented 11 years ago

You have to set rom path to NULL for main_wrap. I guess at the beginning g_extern.fullpath will be an empty string, so checking for that should work. It'll add --menu then instead of ROM path. It's not doing that correctly now apparently, so you're seeing "reading from stdin" and libretro_dummy is false. On PC, when there is no --menu, and no ROM path, it'll try to read from stdin at least.

Also, recall that you #ifdefed out some libretro_dummy stuff in dynamic.c. Could have something to do with it.

I am pretty sure it will work out. I'll be on IRC later today so we can sort this out.

inactive123 commented 11 years ago

We are still not anywhere near there in terms of unifying global init/deinit for both console and PC.

void global_init_drivers(void) { init_drivers_pre(); // Set driver.* function callbacks.

if defined(HAVE_RGUI) || defined(HAVE_RMENU)

driver.video->start(); // Statically starts video driver. Sets driver.video_data.

endif

driver.input_data = driver.input->init();

ifdef HAVE_OVERLAY

if (*g_settings.input.overlay) { driver.overlay = input_overlay_new(g_settings.input.overlay); if (!driver.overlay) RARCH_ERR("Failed to load overlay.\n"); }

endif

}

We will need a solution so that the logic that is being done in driver.video->start() will be done for consoles and/or PCs. I have spent at least two hours today trying to come up with a 'portable' solution for this that would scale across PC and console and in the end I had to throw it all away because it involved me having to 'ifndef' re-entrant deinits and at the end performance took a nosedive and was stuck at below 60fps (with or without any shader stacking).

Also, another thing that is broken about your current approach in 'driver initing' is that it assumes the input driver will always be tied to the video driver, and this is obviously not the case on consoles. So either driver.input_data needs to be 'inited' to something as a separate step somewhere for RARCH_CONSOLE or you just need to refactor the input initing code so that it makes sense for both console and PC.

Themaister commented 11 years ago

Input driver isn't necessarily tied to video driver. It usually is on PC, but doesn't have to be. The video driver can init the input driver directly, if it requires a certain driver (e.g. SDL, X11, Win32, etc). If video driver doesn't init input driver explicitly, it'll try to init input driver "normally".

About reentrancy, it's the good old "who owns the pointer" issue. Who owns what is controlled by driver._data_own. If you let core init drivers from scratch, core will take ownership (set _data_own to true). And on deinit, it will free the driver. This is the way it's done on PC, because of windowed mode being a harsh mistress.

Now, on consoles you want the driver to persist even through reinits, because you're always fullscreen anyways, so after first main_init, you can force driver.video_data_own and driver.input_data_own to false. If they are false, core will not free them on deinit, and assume they're owned by someone else (i.e. frontend). I don't know how this can be made more obvious without having lots of wrapper "manager code".

Anyways, the problem in frontend_console.c now are that there is lots of non-obvious dependencies in-between each step. Will need some very thorough audit for me at least.