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

sm64ex: init at unstable-2020-06-19 #88821

Merged
merged 1 commit into from Aug 22, 2020
Merged

Conversation

IvarWithoutBones
Copy link
Member

@IvarWithoutBones IvarWithoutBones commented May 24, 2020

Motivation for this change

Adds sm64pc, a PC port of Super Mario 64 based off of decompilation.

The assets and such (the port itself extracts these) are copyrighted by Nintendo. Hence the need for the user to supply it themselves.

Note that i added an empty list of makeFlags, this is so you can easily add them as an end user for subjective patches. You can find two of them in the projects readme. For example, one of them includes a (subjectively) better camera, which the end user can now easily enable using overwrites.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@emilazy
Copy link
Member

emilazy commented May 25, 2020

I've licensed this as public domain, as the decompilation itself is that.

There's no explicit license statement or copyright waiver in the repository that I can see, and as the reverse-engineered source code it's based on is modified decompiler output that compiles to an executable bit-identical to the original, it seems almost certain to me that it's legally a derivative work of the original game. As cool as this project is, I think the package must at least be marked as unfree; it would be a massive liability for Hydra to distribute binaries of it.

Edit: Ah, I guess Hydra couldn't build this anyway since this relies on a copy of the original ROM. I'm not sure it's ideal to have a package depend on an absent fixed-output derivation like this, though I don't have better options off the top of my head (an argument to the package feels like the cleanest thing, but that won't work with callPackage). It seems like the extract_assets.py script supports multiple versions of the ROM, whereas fixing the hash in the package means you can only use one specific release.

@IvarWithoutBones
Copy link
Member Author

IvarWithoutBones commented May 25, 2020

There's no explicit license statement or copyright waiver in the repository that I can see

From what I've been told on their Discord server there's none provided, i assumed it was public domain. image

However, when i just looked into this, it seems the AUR PKGBUILD says it's MIT. Not sure what to do here.

And yes, just providing the entire thing (in binary form or something) would be very legally questionable, but since the user supplies the ROM here, and we're not hosting anything copyrighted i think it should be totally fine.

It seems like the extract_assets.py script supports multiple versions of the ROM, whereas fixing the hash in the package means you can only use one specific release.

Indeed, i wanted to support this, and as you said not use a direct hash, but i wasn't sure how to go about it. I've based the user input of the rom on mathematica, as im not aware of a better way to do this.

@emilazy
Copy link
Member

emilazy commented May 25, 2020

"No license provided" isn't the same as "public domain", it's actually the opposite. Things are "all rights reserved" by default; to release something into the public domain requires an explicit waiver of automatic copyright protection (and even then it's only valid in some jurisdictions).

Even if there was a clear statement that all the copyrightable work of the reverse-engineers was MIT-licensed, it still wouldn't mean that the package as a whole can be used and redistributed under those terms, since that would require all the copyright holders of the work to MIT-license their contributions, and Nintendo have an extremely plausible copyright claim to the reverse-engineered source code it's based on (it compiles to an executable bit-identical to theirs, and was almost certainly originally machine-decompiled from it to begin with). In that case, the licensing situation could be documented like:

{
  meta = with stdenv.lib; {
    license = [
      # Original game code
      licenses.unfree
      # Work by reverse-engineers
      licenses.mit
    ];
  };
}

But unfortunately, there's no getting away from the unfree here, short of clean-room reverse engineering the entire game from scratch without any use of a decompiler.

Indeed, i wanted to support this, and as you said not use a direct hash, but i wasn't sure how to go about it. I've based the user input of the rom on mathematica, as im not aware of a better way to do this.

I think the best approach here is probably to take a baseRom argument that replaces the requireFile expression if it's not null so that people can override it if they want. The existing default seems fine to me, especially if it's used in existing packages for proprietary software (I hadn't seen requireFile used before).

@IvarWithoutBones
Copy link
Member Author

IvarWithoutBones commented May 25, 2020

"No license provided" isn't the same as "public domain", it's actually the opposite. Things are "all rights reserved" by default; to release something into the public domain requires an explicit waiver of automatic copyright protection (and even then it's only valid in some jurisdictions).

I wasn't aware of that. Interesting. Since I don't actually see any mention of MIT in the project, should we just go with unfree?

I think the best approach here is probably to take a baseRom argument that replaces the requireFile expression if it's not null so that people can override it if they want. The existing default seems fine to me, especially if it's used in existing packages for proprietary software (I hadn't seen requireFile used before).

Apologies, but I'm quite a beginner at nix. how would i go about doing that? I can't seem to figure it out without encountering infinite recursion.

@kira-bruneau
Copy link
Contributor

kira-bruneau commented May 27, 2020

@IvarWithoutBones Thanks for packaging this! I tried this out and it works perfectly.

Regarding licensing, sm64pc depends on n64-fast32-engine, which has a license stating that the source can be redistributed, but not the binary. This would definitely have to be marked as unfree.

To avoid the infinite recursion, you could rename the argument to something other than baseRom, but you could also just directly set the default:

{ stdenv, fetchFromGitHub, requireFile, python3, pkg-config
, audiofile, SDL2, hexdump, makeFlags ? []
, baseRom ?
  requireFile {
    name = "baserom.us.z64";
    message = ''
      This nix expression requires that baserom.us.z64 is
      already part of the store. To get this file you can dump your US Super Mario 64 cartridge's contents
      and add it to the nix store with nix-store --add-fixed sha256 <FILE>.
    '';
    sha256 = "17ce077343c6133f8c9f2d6d6d9a4ab62c8cd2aa57c40aea1f490b4c8bb21d91";
  }
}:

stdenv.mkDerivation rec {
  ...
  inherit makeFlags baseRom;
  ...
}

@IvarWithoutBones
Copy link
Member Author

IvarWithoutBones commented May 27, 2020

Regarding licensing, sm64pc depends on n64-fast32-engine, which has a license stating that the source can be redistributed, but not the binary. This would definitely have to be marked as unfree.

Ah, okay. Switching to that 👍

To avoid the infinite recursion, you could rename the argument to something other than baseRom, but you could also just directly set the default:

Thank you! learning new things every day haha. I've just pushed a WIP thing that makes use of that, and this works fine except for 1 problem: I can't replace the hash of baseRom based on the region being used. In other languages that'd be a simple if statement, but that doesn't seem to do the trick here. Input would be much appreciated.

Edit: I guess people would be messing with overwrites anyway, so they could easily do that themselves. Though preferably we'd handle that i think.

Note that i also added an region attribute, as we need to set some stuff according to that.

@kira-bruneau
Copy link
Contributor

kira-bruneau commented May 27, 2020

What was the issue you were having with if statements? It should have worked. Although, it might be easier to index a set for this case:

{
  sha256 = {
    "eu" = "0000000000000000000000000000000000000000000000000000000000000000";
    "jp" = "0000000000000000000000000000000000000000000000000000000000000000";
    "us" = "17ce077343c6133f8c9f2d6d6d9a4ab62c8cd2aa57c40aea1f490b4c8bb21d91";
  }.${region};
}

@IvarWithoutBones
Copy link
Member Author

What was the issue you were having with if statements? It should have worked.

I'm not quite sure, there weren't any errors, it kinda just did not work. Either way, your solution indeed seems a lot cleaner, thanks again! Pushed a fixed version, with all the valid hashes according to members of their discord server.

pkgs/games/sm64pc/default.nix Outdated Show resolved Hide resolved
Copy link
Contributor

@TheBrainScrambler TheBrainScrambler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, I tried to build and run it with nixpkgs-review, and it works ! I just noticed that you could add the BETTERCAMERA makeFlag, or at least propose some option to add it.

pkgs/games/sm64pc/default.nix Outdated Show resolved Hide resolved
@IvarWithoutBones
Copy link
Member Author

Added darwin support, as i realized upstream has this. I do not own a Darwin machine to test, but in theory this should work.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/200

@IvarWithoutBones IvarWithoutBones changed the title sm64pc: init at unstable-2020-05-19 sm64ex: init at unstable-2020-06-19 Jun 22, 2020
@IvarWithoutBones
Copy link
Member Author

IvarWithoutBones commented Jun 22, 2020

It appears upstream got moved to sm64pc/sm64ex, so I've changed the derivation accordingly + updated to the latest git rev.

It now complains about not being able to find git, however this is for showing the git rev ingame on their nightly branch, which we are not using so we can just ignore it. It still compiles just fine.

@IvarWithoutBones
Copy link
Member Author

Anything blocking this from getting merged?

Copy link
Contributor

@kira-bruneau kira-bruneau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks, good to me! Unfortunately I don't have merge permissions.

@Lassulus Lassulus merged commit f2e290e into NixOS:master Aug 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants