Previous  1 ... 31, 32, 33, 34, 35  Next
Anyone interested in creating a higan/libretro wrapper? 
Author Message
User avatar

Joined: 2014-10-29 21:24
Posts: 1808
Location: People's Republic of America
 Re: Anyone interested in creating a higan/libretro wrapper?
I just discovered an obscure bug in how the libretro core loads manifests! I checked, and it affects both higan's accuracy profile and nSide's balanced profile.

target-libretro/libretro.cpp
Code:
RETRO_API bool retro_load_game(const retro_game_info *game)
{
  //...
  else if (loading_manifest)
  {
    // Load ROM and RAM from the directory.
    program->medium_paths(id) = Location::dir(game_path);
    program->loaded_manifest(id) = string_view(static_cast<const char *>(game->data), game->size);  //←it's in this statement here
  }
  //...
}

The bug occurs when loading a manifest that has been stored in a cartridge folder. It won't affect standalone ROMs, and it won't take effect when loading program.rom and making icarus generate a manifest.

string_view has a constructor that takes a pointer to character data and an unsigned integer to specify the size. Its declaration is as follows:
string_view::string_view(const char* data, uint size)
. Note that
uint
is an abbreviation of
unsigned int
. Simple enough, right?

But string_view has another constructor, and this one's a doozy. It takes any possible combination of arguments of any type, and they don't even need to be the same type:
template<typename... P> string_view::string_view(P&&... p)
The idea is to convert every argument into a string for concatenation, but this is where the bug comes in:

Because of the rules of C++ overload resolution, the second constructor above will take priority over the first, unless the arguments used are an exact match:
const char*
and
uint
! You can't just use similar types and expect it to work, they need to be identical!
game->data
is converted into a
const char*
(from
const void*
), so that's covered. But the problem is that
game->size
is not converted into a
uint
like it should. The result is that the size will be converted into a string and appended to the end of the manifest like this:

Code:
game
  label: Sample
  board: LOROM
    memory
      type: ROM
      size: 0x80000
      category: Program106

The
106
at the end is the size of the manifest in bytes before the number was appended. Normally, this wouldn't be a problem if the manifest has a line feed ("\n") at the end like icarus's generated manifests. In that case, “107” would be an empty root node that would just be ignored. However, I deliberately picked an example that omits the terminating line feed —because that is legal and has been since higan v093— in order to show how the bug can corrupt a manifest. In this case, it changes the contents of the
category
node from
Program
to
Program106
. In higan v106r10 and later, this will completely hide the ROM, making the game appear to have no ROM at all. Even renaming the file to “program106.rom” won't work because higan no longer supports filename overriding.

game->size
's type is
std::size_t
, which is not guaranteed to be an exact match for
unsigned int
. On an x86-64 system, I believe
std::size_t
will be
long long unsigned int
, indicating a 64-bit unsigned integer as opposed to 32-bit as
unsigned int
would be. My manifest for Tengai Makyou Zero is just over a single kilobyte long. I don't think there is any danger of a manifest naturally exceeding 4 GiB, right? I'd try actually loading a file that big, but I don't want to run the risk of having my computer hang when it does so.

What needs to be done is to add an explicit cast to
game->size
to declare it as a
uint
(or
unsigned int
). That means to use the following code instead:

target-libretro/libretro.cpp
Code:
RETRO_API bool retro_load_game(const retro_game_info *game)
{
  //...
  else if (loading_manifest)
  {
    // Load ROM and RAM from the directory.
    program->medium_paths(id) = Location::dir(game_path);
    program->loaded_manifest(id) = string_view(static_cast<const char *>(game->data), (uint)game->size);
  }
  //...
}

You can replace
(uint)
with
(unsigned)
if you want. Both names refer to the same type.

_________________
bsnes-mcfly: A port of the Qt GUI from v073 to v106.
nSide: A higan fork w/NES boards and peripherals and Sonic & Knuckles Lock-On.
Dragon Quest I & II RPGOne Beran Inn bugfix


2018-03-13 15:28

Joined: 2014-09-27 09:29
Posts: 713
 Re: Anyone interested in creating a higan/libretro wrapper?
ha, wow, nice catch!


2018-03-13 22:25
User avatar

Joined: 2014-09-25 13:52
Posts: 8242
 Re: Anyone interested in creating a higan/libretro wrapper?
template<typename...>
and implicit conversion constructors are truly dangerous in C++.

I have to commit atrocities in nall/string,natural,integer to make them usable, but I've been burned in substantial ways in the past by these. I suspect it will occur more in the future.

_________________
What the hell's going on? Can someone tell me please?
Why I'm switching faster than the channels on TV.
I'm black, then I'm white. No, something isn't right.
My enemy's invisible, I don't know how to fight.


2018-03-13 23:09
User avatar

Joined: 2014-09-25 13:57
Posts: 2119
Location: Australia
 Re: Anyone interested in creating a higan/libretro wrapper?
I've committed the change to my private copy of the libretro branch, but I won't make it public because higan WIPs are still going through manifest-format upheavals.

_________________
Maintainer of the unofficial git repository for higan.

The ending of the words is ALMSIVI.


2018-03-14 02:07
User avatar

Joined: 2014-10-29 21:24
Posts: 1808
Location: People's Republic of America
 Re: Anyone interested in creating a higan/libretro wrapper?
Because Microsoft bought out GitHub, I have deleted my GitHub account. That means, for the time being, the balanced profile's libretro core is offline. I will register for a GitLab account and migrate my repositories there, and once I do, I will indicate the new location of the balanced profile's libretro core here.

_________________
bsnes-mcfly: A port of the Qt GUI from v073 to v106.
nSide: A higan fork w/NES boards and peripherals and Sonic & Knuckles Lock-On.
Dragon Quest I & II RPGOne Beran Inn bugfix


2018-06-04 14:24

Joined: 2014-09-27 09:29
Posts: 713
 Re: Anyone interested in creating a higan/libretro wrapper?
Ok, no problem. We're taking a wait-and-see approach with github, but we might be joining you soon...


2018-06-04 16:15
User avatar

Joined: 2014-09-27 09:59
Posts: 419
 Re: Anyone interested in creating a higan/libretro wrapper?
hunterk wrote:
Ok, no problem. We're taking a wait-and-see approach with github, but we might be joining you soon...

Ditto.

_________________
Slackware Linux 8.1 | AMD Athlon XP 2100+ @ 1733MHz | ASUS A7V333 Motherboard | 512MB 333MHz DDR RAM | VisionTek GeForce 3 | Ensoniq AudioPCI | Western Digital WD800BB 80GB HDD | Enermax Whisper EG465P Power Supply | Lian-Li PC60 PC Case


2018-06-04 17:42

Joined: 2017-11-26 23:37
Posts: 65
 Re: Anyone interested in creating a higan/libretro wrapper?
Concerning gitlab I would like to point out this article.

https://venturebeat.com/2018/04/06/why- ... gle-cloud/

Personally I don't see it as much of a benefit to drop a microsoft owned product for one hosted on the google cloud.

I think the ideal solution is a self-hosted repo using software like gitea or even cgit, but this may not be practical for some. For free software projects notabug could be an alternative.


2018-06-15 16:36
User avatar

Joined: 2014-09-27 09:56
Posts: 1674
 Re: Anyone interested in creating a higan/libretro wrapper?
There seems to be a bug in the libretro higan core's MSU-1 handling. It seems like the core is always enabling the MSU-1, even when there is no manifest, no .msu file, and no .pcm files. This leads to problems with some games' SPC fallback code, causing issues like completely muting the music, or even complete softlocks in some cases. This does not occur in standalone higan, only in RetroArch. It also doesn't occur in other libretro cores like Snes9x.

_________________
byuu wrote:
Surely I can unite the vi vs emacs crowd like I have the ZSNES vs Snes9X crowd :)



higan WIP builds available here


2018-10-07 00:42

Joined: 2014-09-27 09:27
Posts: 2384
Location: Australia
 Re: Anyone interested in creating a higan/libretro wrapper?
That's a report from the Link to the Past Randomizer project right?

_________________
Windows 10 Pro x64 | Intel Core i7 920 @ 3.6GHz | ASUS P6T Motherboard | 24GB 1140~MHz DDR3 RAM | MSI Geforce 1070Ti Gamer | Integrated Sound | Samsung 860 Pro 512GB SSD | Corsair AX760 Power Supply | Fractal Design Define R5 PC case


2018-10-07 04:44
Previous  1 ... 31, 32, 33, 34, 35  Next