Skip to content

Commit

Permalink
Switch
Browse files Browse the repository at this point in the history
Co-authored-by: Cpasjuste <[email protected]>

Signed-off-by: Caroline Bell <[email protected]>
  • Loading branch information
Stary2001 authored and halotroop2288 committed Jan 12, 2024
1 parent 6c81413 commit f950ebd
Show file tree
Hide file tree
Showing 46 changed files with 3,263 additions and 55 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ jobs:
name: 🏁 Windows
needs: static-checks
uses: ./.github/workflows/windows_builds.yml

switch-build:
name: 🔄 Switch
needs: static-checks
uses: ./.github/workflows/switch_builds.yml
48 changes: 48 additions & 0 deletions .github/workflows/switch_builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: 🔄 Switch Builds
on:
workflow_call:

# Global Cache Settings
env:
GODOT_BASE_BRANCH: 3.5
SCONS_CACHE_LIMIT: 4096

jobs:
switch-template:
runs-on: ubuntu-latest
container: devkitpro/devkita64

name: Template (target=release, tools=no)

steps:
- uses: actions/checkout@v3

# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: switch-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
- name: Install scons from pip
run: |
sudo apt-get update
sudo apt-get -y install python3-pip
sudo python3 -m pip install scons
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons -j2 verbose=yes warnings=all werror=no platform=switch target=release tools=no
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,13 @@ $RECYCLE.BIN/
*.msm
*.msp
*.lnk

# Templates
templates/
/*.zip
/*.tpz

# Switch
*.nro
switch/
config/nx-hbmenu/
48 changes: 48 additions & 0 deletions README-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Godot for Switch

It's a port of the Godot open source game engine to the Switch, via homebrew libraries provided by devkitPro/switchbrew.
See the original [README.md](./README.md) for info about Godot.

## Releases

See [the GitHub releases page](https://github.com/Homebrodot/Godot/releases) for pre-built editors for Windows, macOS and
Linux.

## How do I export my game?

The editor builds above add a `Switch` exporter to the list - it will generate a .nro and a .pck file that can be
transferred to your Switch.
If additional debugging is required, sending the nro via nxlink (make sure to send it to the right place with the -p
argument) will allow the output of the console to be viewed on PC.

## How to build?

You shouldn't need to build the engine if you use a release as the templates should be included - these instructions are
for development!

[See the official docs](https://docs.godotengine.org/en/latest/development/compiling/)
for compilation instructions for every officially supported platform.

### For Switch:

Install these packages from [devkitPro pacman](https://devkitpro.org/wiki/devkitPro_pacman):
`switch-pkg-config switch-freetype switch-bulletphysics switch-libtheora switch-libpcre2 switch-mesa switch-opusfile switch-mbedtls switch-libwebp switch-libvpx switch-miniupnpc switch-libzstd switch-wslay`
then run `scons platform=switch` in the root of the repo. Add `target=release` to build for release instead of debug.

Then, to build an engine release for Switch,
run `./scripts/create-switch-release.sh` in the root of the repo.

Or to build an export template for the editor,
run `./scripts/create-switch-template.sh` in the root of the repo.

## How can I get help?

Either make an issue on this repo, or join the [Discord](https://discord.gg/yUC3rUk "Homebrodot - Godot Homebrew Hub")!

# Credits

* Thanks to devkitPro / switchbrew for producing devkitA64/libnx.
* Extra special thanks to fincs from devkitPro - This port would have never been possible without their port of the open
source nouveau graphics driver.
* cpasjuste for help with development.
* fhidalgosola/utnad for their port / help with development.
74 changes: 33 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,79 +1,71 @@
# Godot Engine
[![Godot Engine logo](/logo.png)](https://godotengine.org)

<p align="center">
<a href="https://godotengine.org">
<img src="logo_outlined.svg" width="400" alt="Godot Engine logo">
</a>
</p>
## Godot Engine

## 2D and 3D cross-platform game engine
Homepage: https://godotengine.org

**[Godot Engine](https://godotengine.org) is a feature-packed, cross-platform
game engine to create 2D and 3D games from a unified interface.** It provides a
comprehensive set of [common tools](https://godotengine.org/features), so that users can focus on making games
without having to reinvent the wheel. Games can be exported with one click to a
number of platforms, including the major desktop platforms (Linux, macOS,
Windows), mobile platforms (Android, iOS), as well as Web-based platforms
(HTML5) and
[consoles](https://docs.godotengine.org/en/latest/tutorials/platform/consoles.html).
#### 2D and 3D cross-platform game engine

## Free, open source and community-driven
Godot Engine is a feature-packed, cross-platform game engine to create 2D and
3D games from a unified interface. It provides a comprehensive set of common
tools, so that users can focus on making games without having to reinvent the
wheel. Games can be exported in one click to a number of platforms, including
the major desktop platforms (Linux, Mac OSX, Windows) as well as mobile
(Android, iOS) and web-based (HTML5) platforms.

Godot is completely free and open source under the very permissive [MIT license](https://godotengine.org/license).
#### Free, open source and community-driven

Godot is completely free and open source under the very permissive MIT license.
No strings attached, no royalties, nothing. The users' games are theirs, down
to the last line of engine code. Godot's development is fully independent and
community-driven, empowering users to help shape their engine to match their
expectations. It is supported by the [Software Freedom Conservancy](https://sfconservancy.org/)
expectations. It is supported by the Software Freedom Conservancy
not-for-profit.

Before being open sourced in [February 2014](https://github.com/godotengine/godot/commit/0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac),
Godot had been developed by [Juan Linietsky](https://github.com/reduz) and
[Ariel Manzur](https://github.com/punto-) (both still maintaining the project) for several
Before being open sourced in February 2014, Godot had been developed by Juan
Linietsky and Ariel Manzur (both still maintaining the project) for several
years as an in-house engine, used to publish several work-for-hire titles.

![Screenshot of a 3D scene in the Godot Engine editor](https://raw.githubusercontent.com/godotengine/godot-design/master/screenshots/editor_tps_demo_1920x1080.jpg)
![Screenshot of a 3D scene in Godot Engine](https://download.tuxfamily.org/godotengine/media/screenshots/editor_3d_fracteed.jpg)

## Getting the engine
### Getting the engine

### Binary downloads
#### Binary downloads

Official binaries for the Godot editor and the export templates can be found
[on the homepage](https://godotengine.org/download).

### Compiling from source
#### Compiling from source

[See the official docs](https://docs.godotengine.org/en/latest/development/compiling/)
for compilation instructions for every supported platform.

## Community and contributing
### Community and contributing

Godot is not only an engine but an ever-growing community of users and engine
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).

The best way to get in touch with the core engine developers is to join the
[Godot Contributors Chat](https://chat.godotengine.org).
To get in touch with the developers, the best way is to join the
[#godotengine IRC channel](https://webchat.freenode.net/?channels=godotengine)
on Freenode.

To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).

## Documentation and demos
### Documentation and demos

The official documentation is hosted on [ReadTheDocs](https://docs.godotengine.org).
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).

The [class reference](https://docs.godotengine.org/en/latest/classes/)
is also accessible from the Godot editor.
is also accessible from within the engine.

We also maintain official demos in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
as well as a list of [awesome Godot community resources](https://github.com/godotengine/awesome-godot).
The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
as well.

There are also a number of other
[learning resources](https://docs.godotengine.org/en/latest/community/tutorials.html)
provided by the community, such as text and video tutorials, demos, etc.
Consult the [community channels](https://godotengine.org/community)
for more information.
There are also a number of other learning resources provided by the community,
such as text and video tutorials, demos, etc. Consult the [community channels](https://godotengine.org/community)
for more info.

[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
[![Travis Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bfiihqq6byxsjxxh/branch/master?svg=true)](https://ci.appveyor.com/project/akien-mga/godot)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/godotengine/godot)](https://www.tickgit.com/browse?repo=github.com/godotengine/godot)
8 changes: 8 additions & 0 deletions core/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
}
#endif

#ifdef HORIZON_ENABLED
if (!found) {
if (_load_resource_pack("romfs:/game.pck")) {

This comment has been minimized.

Copy link
@halotroop2288

halotroop2288 Feb 1, 2024

Member

@Homebrodot/nintendo-switch @Homebrodot/godot-3 Can't we just override OS.get_resource_path in os_switch.cpp to avoid making an engine edit here?

// OS will call ProjectSettings->get_resource_path which will be empty if not overridden!
// If the OS would rather use a specific location, then it will not be empty.
resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/");

This comment has been minimized.

Copy link
@hokaze

hokaze Feb 1, 2024

@Homebrodot/nintendo-switch @Homebrodot/godot-3 Can't we just override OS.get_resource_path in os_switch.cpp to avoid making an engine edit here?

If we wanted to be able to remove the HORIZON_ENABLED block and let the generic Windows/Linux code for
finding the PCK file handle it, wouldn't that require an override on OS::get_executable_path instead of OS::get_resource_path for os_switch?

Not looked too hard at it, but I thought OS::get_resource_path is for the editor to find the absolute path to res:// on the host filesystem and is mostly used when loading godot project file, while the executable path is what it uses when looking for PCK files, with the latter having several fallbacks for finding the file, but all of them rely on the exec path:

	String exec_path = OS::get_singleton()->get_executable_path();

	if (exec_path != "") {
		// We do several tests sequentially until one succeeds to find a PCK,
		// and if so we attempt loading it at the end.

		// Attempt with PCK bundled into executable.
		bool found = _load_resource_pack(exec_path);

		// Attempt with exec_name.pck.
		// (This is the usual case when distributing a Godot game.)
		String exec_dir = exec_path.get_base_dir();
		String exec_filename = exec_path.get_file();
		String exec_basename = exec_filename.get_basename();

		// Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle)
		// or the exec path's basename + '.pck' (Windows).
		// We need to test both possibilities as extensions for Linux binaries are optional
		// (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck').

		...

		if (!found) {
			// Try to load data pack at the location of the executable.
			// As mentioned above, we have two potential names to attempt.
			found = _load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) || _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"));
		}

		if (!found) {
			// If we couldn't find them next to the executable, we attempt
			// the current working directory. Same story, two tests.
			found = _load_resource_pack(exec_basename + ".pck") || _load_resource_pack(exec_filename + ".pck");
		}

		// If we opened our package, try and load our project.
		if (found) {
			Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
			if (err == OK && !p_ignore_override) {
				// Load override from location of the executable.
				// Optional, we don't mind if it fails.
				_load_settings_text(exec_path.get_base_dir().plus_file("override.cfg"));
			}
			return err;
		}
	}

Otherwise, yeah, I agree.

It makes sense to offload all the homebrew platform-specific stuff we can outside of the core and the editor where possible, and overriding the path in the OS methods for the homebrew platforms is a nice workaround.

found = true;
}
}
#endif

if (!found) {
// Try to load data pack at the location of the executable.
// As mentioned above, we have two potential names to attempt.
Expand Down
15 changes: 14 additions & 1 deletion drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,20 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#ifndef GLES_OVER_GL
#define glClearDepth glClearDepthf

#if defined IPHONE_ENABLED || defined ANDROID_ENABLED
// enable extensions manually for android and ios
#ifndef UWP_ENABLED
#include <dlfcn.h> // needed to load extensions
#endif
#endif

#ifdef IPHONE_ENABLED

#include <OpenGLES/ES2/glext.h>
//void *glRenderbufferStorageMultisampleAPPLE;
//void *glResolveMultisampleFramebufferAPPLE;
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE
#elif defined(ANDROID_ENABLED)
#elif defined ANDROID_ENABLED || defined HORIZON_ENABLED

#include <GLES2/gl2ext.h>
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
Expand Down Expand Up @@ -6294,6 +6296,17 @@ void RasterizerStorageGLES2::initialize() {
config.render_to_mipmap_supported = config.extensions.has("GL_OES_fbo_render_mipmap") && config.extensions.has("GL_EXT_texture_lod");
#endif

// If the desktop build is using S3TC, and you export / run from the IDE for android, if the device supports
// S3TC it will crash trying to load these textures, as they are not exported in the APK. This is a simple way
// to prevent Android devices trying to load S3TC, by faking lack of hardware support.

// Switch: this happens on Horizon too.
#ifndef TOOLS_ENABLED
#if defined ANDROID_ENABLED || defined HORIZON_ENABLED
config.s3tc_supported = false;
#endif
#endif

#ifdef GLES_OVER_GL
config.use_rgba_2d_shadows = false;
config.support_depth_texture = true;
Expand Down
3 changes: 1 addition & 2 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8086,11 +8086,10 @@ void RasterizerStorageGLES3::initialize() {
// If the desktop build is using S3TC, and you export / run from the IDE for android, if the device supports
// S3TC it will crash trying to load these textures, as they are not exported in the APK. This is a simple way
// to prevent Android devices trying to load S3TC, by faking lack of hardware support.
#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED)
#if defined(ANDROID_ENABLED) || defined(IPHONE_ENABLED) || defined(HORIZON_ENABLED)
config.s3tc_supported = false;
#endif
#endif

// not yet detected on GLES3 (is this mandated?)
config.support_npot_repeat_mipmap = true;

Expand Down
8 changes: 8 additions & 0 deletions drivers/unix/dir_access_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,9 @@ String DirAccessUnix::read_link(String p_file) {

p_file = fix_path(p_file);

#ifdef HORIZON_ENABLED
return p_file;
#else
char buf[256];
memset(buf, 0, 256);
ssize_t len = readlink(p_file.utf8().get_data(), buf, sizeof(buf));
Expand All @@ -421,9 +424,13 @@ String DirAccessUnix::read_link(String p_file) {
link.parse_utf8(buf, len);
}
return link;
#endif
}

Error DirAccessUnix::create_link(String p_source, String p_target) {
#ifdef HORIZON_ENABLED
return FAILED;
#else
if (p_target.is_rel_path())
p_target = get_current_dir().plus_file(p_target);

Expand All @@ -435,6 +442,7 @@ Error DirAccessUnix::create_link(String p_source, String p_target) {
} else {
return FAILED;
}
#endif
}

uint64_t DirAccessUnix::get_space_left() {
Expand Down
7 changes: 4 additions & 3 deletions drivers/unix/file_access_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

#include <errno.h>

#if defined(UNIX_ENABLED)
#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED)
#include <unistd.h>
#endif

Expand Down Expand Up @@ -130,6 +130,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
return last_error;
}

#ifndef HORIZON_ENABLED
// Set close on exec to avoid leaking it to subprocesses.
int fd = fileno(f);

Expand All @@ -142,7 +143,7 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
fcntl(fd, F_SETFD, opts | FD_CLOEXEC);
#endif
}

#endif
last_error = OK;
flags = p_mode_flags;
return OK;
Expand Down Expand Up @@ -279,7 +280,7 @@ bool FileAccessUnix::file_exists(const String &p_path) {
return false;
}

#ifdef UNIX_ENABLED
#if defined(UNIX_ENABLED) || defined(HORIZON_ENABLED)
// See if we have access to the file
if (access(filename.utf8().get_data(), F_OK)) {
return false;
Expand Down
Loading

0 comments on commit f950ebd

Please sign in to comment.