Subject: [bug#37714] Add renpy package

From: Leo Prikler <[email-masked]>
Date: Sat, 12 Oct 2019 09:20:56 +0200

This patch adds the Ren'py Visual Novel engine split into four outputs:
- "out": contains the engine itself. Since Guix differs strongly from
the platforms Ren'py usually runs on, we ship our own Ren'py main file.
- "launcher": The Ren'py launcher, that people would normally expect
when invoking renpy -- it does not seem very usable in Guix, though.
- "the-question": An example game, that ships with Ren'py.
- "tutorial": The tutorial that ships with Ren'py.

Ren'py also ships its own version of pygame. They call it pygame_sdl2
since it's a reimplementation of pygame using SDL2, but the tags make
it very clear, that it is developed alongside Ren'py.
From edbb52a156a9129a7f5a74e5d6afc03ae1adf2dd Mon Sep 17 00:00:00 2001
From: Leo Prikler <[email-masked]>
Date: Sat, 12 Oct 2019 08:34:31 +0200
Subject: [PATCH] gnu: Add python2-renpy

* gnu/packages/game-development: (python2-pygame-for-renpy): New procedure.
(python2-renpy): New variable.
---
 gnu/packages/game-development.scm | 240 ++++++++++++++++++++++++++++++
 1 file changed, 240 insertions(+)

diff --git a/gnu/packages/game-development.scm b/gnu/packages/game-development.scm
index 7fc0122faa..134664e773 100644
--- a/gnu/packages/game-development.scm
+++ b/gnu/packages/game-development.scm
@@ -971,6 +971,246 @@ to create fully featured games and multimedia programs in the python language.")
 (define-public python2-pygame
   (package-with-python2 python-pygame))
 
+(define (python2-pygame-for-renpy version hash)
+  (package
+   (inherit python2-pygame)
+   (name "python2-pygame-for-renpy")
+   (version version)
+    (source
+     (origin
+      (method git-fetch)
+      (uri (git-reference
+            (url "https://github.com/renpy/pygame_sdl2.git")
+            (commit (string-append "renpy-" version))))
+      (sha256
+       (base32
+        hash))
+      (file-name (git-file-name name version))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f                ; tests require pygame to be installed first
+       #:python ,python-2
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'set-paths 'set-sdl-vars
+           (lambda* (#:key inputs #:allow-other-keys)
+             (setenv "PYGAME_SDL2_CFLAGS"
+                     (string-append "-I"
+                                    (assoc-ref inputs "sdl-union")
+                                    "/include/SDL2 -D_REENTRANT"))
+             (setenv "PYGAME_SDL2_LDFLAGS"
+                     (string-append "-L"
+                                    (assoc-ref inputs "sdl-union")
+                                    "/lib -Wl,-rpath,"
+                                    (assoc-ref inputs "sdl-union")
+                                    "/lib -Wl,--enable-new-dtags -lSDL2"))
+             #t)))))
+    (inputs
+     `(("sdl-union"
+        ,(sdl-union (list sdl2 sdl2-image sdl2-mixer sdl2-ttf)))))
+    (native-inputs
+     `(("python2-cython" ,python2-cython)))
+    (home-page "http://www.renpy.org/")
+    (synopsis "Reimplementation of the Pygame API using SDL2")
+    (license (list license:lgpl2.1 license:zlib))))
+
+(define-public python2-renpy
+  (package
+   (name "python2-renpy")
+   (version "7.3.4.596")
+    (source
+     (origin
+      (method git-fetch)
+      (uri (git-reference
+            (url "https://github.com/renpy/renpy.git")
+            (commit version)))
+      (sha256
+       (base32
+        "11g01bm1bxmc5f7l8ybaf8lg27i3fhy4i69dpwdsalv03i5xbw6y"))
+      (file-name (git-file-name name version))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f ; can't really run renpy in guixbuilder
+       #:python ,python-2
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'set-paths 'set-build-vars
+           (lambda* (#:key inputs #:allow-other-keys)
+             (setenv "RENPY_CYTHON"
+                     (string-append (assoc-ref inputs "python2-cython")
+                                    "/bin/cython"))
+             (setenv "RENPY_DEPS_INSTALL"
+                     (string-join
+                      (map cdr inputs)
+                      ":"))
+             #t))
+         (replace 'build
+           (lambda args
+             (apply
+              (lambda* (build-root #:key inputs outputs #:allow-other-keys)
+                (chdir "module")
+                (apply (assoc-ref %standard-phases 'build) args)
+                (chdir build-root)
+                (delete-file "renpy/__init__.pyc")
+                (invoke "python" "-m" "compileall" "renpy"))
+              (getcwd) args)
+             #t))
+         (replace 'install
+           (lambda args
+             (apply
+              (lambda* (build-root #:key inputs outputs #:allow-other-keys)
+                (let* ((pygame (assoc-ref inputs "python2-pygame"))
+                       (out (assoc-ref outputs "out"))
+                       (site (string-append "/lib/python"
+                                            ,(version-major+minor
+                                              (package-version python-2))
+                                            "/site-packages")))
+                  (chdir "module")
+                  (apply (assoc-ref %standard-phases 'install) args)
+                  (chdir build-root)
+                  (copy-recursively "renpy"
+                                    (string-append out site "/renpy"))))
+              (getcwd) args)
+             #t))
+
+         (add-after 'install 'install-renpy
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (let* ((source (assoc-ref inputs "source"))
+                    (pygame (assoc-ref inputs "python2-pygame"))
+
+                    (site (string-append "/lib/python"
+                                         ,(version-major+minor
+                                           (package-version python-2))
+                                         "/site-packages"))
+
+                    (out (assoc-ref outputs "out"))
+                    (bin/renpy (string-append out "/bin/renpy")))
+               (chdir source)
+               (mkdir-p (string-append out "/bin"))
+
+               (copy-recursively "renpy/common"
+                                 (string-append out "/share/renpy/common"))
+
+               (call-with-output-file bin/renpy
+                 (lambda (port)
+                   (format port "#!~a~%" (which "python2"))
+                   (format port "
+from __future__ import print_function
+
+import os
+import sys
+import warnings
+
+def path_to_common(renpy_base):
+    return renpy_base + \"/common\"
+
+def path_to_saves(gamedir, save_directory=None):
+    import renpy  # @UnresolvedImport
+
+    if save_directory is None:
+        save_directory = renpy.config.save_directory
+        save_directory = renpy.exports.fsencode(save_directory)
+
+    if not save_directory:
+        return gamedir + \"/saves\"
+
+    return os.path.expanduser(\"~~/.renpy/\" + save_directory)
+
+def path_to_renpy_base():
+    return \"~a\"
+
+def main():
+    renpy_base = path_to_renpy_base()
+    try:
+        import renpy.bootstrap
+        import renpy.arguments
+    except ImportError:
+        print(\"\"\"Could not import renpy.bootstrap.
+Please ensure you decompressed Ren'Py correctly, preserving the directory
+structure.\"\"\", file=sys.stderr)
+        raise
+
+    args = renpy.arguments.bootstrap()
+    if not args.basedir:
+        print(\"\"\"This Ren'py requires a basedir to launch.
+The basedir is the directory, in which .rpy files live -- usually the 'game'
+subdirectory of a game packaged by Ren'py.
+
+If you want the Ren'py launcher, use renpy-launcher from python2-renpy:launcher
+instead.\"\"\", file=sys.stderr)
+        sys.exit()
+
+    renpy.bootstrap.bootstrap(renpy_base)
+
+if __name__ == \"__main__\":
+    main()
+"
+                           (string-append out "/share/renpy"))))
+
+               (chmod bin/renpy #o755)
+
+               (wrap-program bin/renpy
+                             `("PYTHONPATH" prefix
+                               (,(string-append out site)
+                                ,(string-append pygame site))))
+               #t)))
+         (add-after 'install 'install-games
+           (lambda* (#:key outputs #:allow-other-keys)
+             (define renpy (assoc-ref outputs "out"))
+             (define* (install-renpy-game #:key output game name (renpy renpy)
+                                          #:allow-other-keys)
+               (let* ((name (or name (basename game)))
+                      (launcher (string-append output "/bin/renpy-" name))
+                      (share (string-append output "/share/renpy/" name)))
+                 (copy-recursively (string-append game "/game") share)
+                 (mkdir-p (string-append output "/bin"))
+                 (with-output-to-file launcher
+                   (lambda ()
+                     (format #t
+                             "#!~a~%~a ~a \"$@\""
+                             (which "bash")
+                             (string-append renpy "/bin/renpy")
+                             share)))
+                 (chmod launcher #o755)))
+
+             (install-renpy-game #:output (assoc-ref outputs "launcher")
+                                 #:game "launcher")
+
+             (install-renpy-game #:output (assoc-ref outputs "the-question")
+                                 #:game "the_question"
+                                 #:name "the-question")
+
+             (install-renpy-game #:output (assoc-ref outputs "tutorial")
+                                 #:game "tutorial")))
+         ;; we already do our own wrapping during 'install-renpy
+         (delete 'wrap))))
+    (inputs
+     `(("ffmpeg" ,ffmpeg)
+       ("freetype" ,freetype)
+       ("glew" ,glew)
+       ("libpng" ,libpng)
+       ("sdl-union"
+        ,(sdl-union (list sdl2 sdl2-image sdl2-mixer sdl2-ttf)))
+       ("python" ,python)))
+    (outputs
+     (list "out" "launcher" "tutorial" "the-question"))
+    (propagated-inputs
+     `(("python2-pygame"
+        ,(python2-pygame-for-renpy
+          version
+          "1gwbqkyv7763813x7nmzb3nz4r8673d33ggsp6lgp1d640rimlpb"))))
+    (native-inputs
+     `(("python2-cython" ,python2-cython)))
+    (home-page "http://www.renpy.org/")
+    (synopsis "The Ren'Py Visual Novel Engine -- libary files")
+    (description "Ren'Py is a visual novel engine -- used by thousands of
+creators from around the world -- that helps you use words, images, and sounds
+to tell interactive stories that run on computers and mobile devices. These can
+be both visual novels and life simulation games. The easy to learn script
+language allows anyone to efficiently write large visual novels, while its
+Python scripting is enough for complex simulation games.")
+    (license license:x11)))
+
 (define-public grafx2
   (package
     (name "grafx2")
-- 
2.23.0