diff --git a/.gitignore b/.gitignore
index f15e789cc4bf..0c8be1977780 100644
--- a/.gitignore
+++ b/.gitignore
@@ -371,6 +371,5 @@ templates/
# Switch
*.nro
-*.nacp
-/switch/
-/config/nx-hbmenu/
+switch/
+config/nx-hbmenu/
diff --git a/BUILDING-switch.md b/BUILDING-switch.md
deleted file mode 100644
index 2c9df475cd51..000000000000
--- a/BUILDING-switch.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Building for Nintendo Switch
-
-These steps must be done under Linux / Windows Subsystem for Linux (WSL) or MSYS2 on Windows.
-
-## Dependencies
-
-If you haven't done so already, install the dependencies called for by the [official Godot docs](https://docs.godotengine.org/en/3.5/development/compiling/compiling_for_x11.html)
-
-1. Install [devkitPro pacman] or add DKP to your existing pacman configuration:
-2. Install the required packages from the terminal
- ```sh
- # On systems without pacman pre-installed (Such as Debian, Ubuntu):
- sudo dkp-pacman -S 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
- ```
- OR
- ```sh
- # On systems with pacman pre-installed (Such as Arch, Manjaro, MSYS2):
- sudo pacman -S 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
-
-## Building
-
-1. Run `scons platform=switch` in the root of the repo.
- Add `target=release` to the end to build for release instead of debug.
-2. Run `misc/scripts/build/create-switch-release.sh` from inside the `bin` folder
- to create an installable release for your Switch.
-3. Run `misc/scripts/build/create-switch-template.sh` from inside the `bin` folder
- to create an export template for your editor.
-
-# Exporting for Nintendo Switch
-
-The [editor releases] add a `Switch` exporter to the list -
-it can generate a Switch homebrew NRO or a generic Godot PCK file
-that can be transferred to your Switch.
-
-If additional debugging is required, sending the NRO file 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.
-
-# Need help?
-
-Either make an issue on this repo, or join the [Discord](https://discordapp.com/invite/yUC3rUk)!
-
-[editor releases]:https://github.com/Homebrodot/godot/releases/latest
-[devkitPro pacman]:https://devkitpro.org/wiki/devkitPro_pacman
diff --git a/BUILDING-vita.md b/BUILDING-vita.md
deleted file mode 100644
index 530d78815b46..000000000000
--- a/BUILDING-vita.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# Building for PS Vita or PS TV
-
-These steps must be done under Linux / Windows Subsystem for Linux (WSL).
-
-## Dependencies
-
-If you haven't done so already, install the dependencies called for by the [official Godot docs](https://docs.godotengine.org/en/3.5/development/compiling/compiling_for_x11.html)
-
-1. Install [VitaSDK]
-
-
- ```sh
- # Clone and bootstrap
- git clone https://github.com/vitasdk/vdpm
- cd vdpm
- ./bootstrap-vitasdk.sh
- # Add to PATH (add this to ~/.bashrc for persistence after reboot)
- export VITASDK=/usr/local/vitasdk
- export PATH=$VITASDK/bin:$PATH # add vitasdk tool to $PATH
- # Finish install
- ./install-all.sh
- # Update
- vitasdk-update
- ```
-
-
-2. Install [PVR-PSP2]
-
-
- ```sh
- # Clone, build and install
- git clone https://github.com/isage/vita-packages-extra
- cd vita-packages-extra/pvr_psp2
- vita-makepkg
- vdpm *-arm.tar.xz
- ```
-
-
-
-## Building
-
-1. Run `scons platform=vita` in the root of the repo.
- Add `target=release` to the end to build for release instead of debug.
-
-# Exporting for PS Vita or PS TV
-
-The [editor releases] add a `Vita` exporter to the list -
-it will generate a homebrew VPK file that can be installed on
-your PlayStation Vita or PlayStation TV with VitaShell.
-
-# Need help?
-
-Either make an issue on this repo, or join the [Discord](https://discordapp.com/invite/yUC3rUk)!
-
-[editor releases]:https://github.com/Homebrodot/godot/releases/latest
-[VitaSDK]:https://vitasdk.org/
-[PVR-PSP2]:https://github.com/GrapheneCt/PVR_PSP2
diff --git a/README-homebrodot.md b/README-homebrodot.md
deleted file mode 100644
index 794f746b9cbd..000000000000
--- a/README-homebrodot.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Homebrodot
-
-It's a port of the Godot open source game engine to homebrew platforms,
-using homebrew libraries such as LibNX and [VitaSDK].
-See the original [README.md](./README.md) for info about Godot.
-
-## Releases
-
-See [the GitHub releases page](https://github.com/Hombrodot/godot/releases)
-for pre-built editors for Windows, macOS, and Linux,
-and export templates for all supported platforms.
-
-## How do I export my game?
-
-Instructions for platforms supported by Homebrodot can be found below.
-
-- [Nintendo Switch](./BUILDING-switch.md#Exporting-for-Nintendo-Switch)
-- [PlayStation Vita / PS TV](./BUILDING-vita.md#Exporting-for-PS-Vita-or-PS-TV)
-
-Otherwise, please see the [Godot docs].
-
-## 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 engine developers!**
-
-Please see the [Godot docs]
-for compilation instructions for officially Godot platform.
-***These are also useful for learning the basic requirements.***
-
-Instructions for platforms supported by Homebrodot can be found here:
-
-- [Nintendo Switch](./BUILDING-switch.md#Building-for-Nintendo-Switch)
-- [PlayStation Vita / PS TV](./BUILDING-vita.md#Building-for-PS-Vita-or-PS-TV)
-
-## 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] and [@switchbrew] for producing devkitA64/libnx.
-- Thanks to the [@VitaSDK] team for producing [VitaSDK].
-- Extra special thanks to [@fincs] from devkitPro.
- The Switch port would have never been possible without their port of the open source nouveau graphics driver.
-- Thanks to [@cpasjuste] for help with development.
-- Thanks to [@fhidalgosola]/utnad for their Switch port / help with development.
-
-[@devkitPro]:https://github.com/devkitPro
-[@switchbrew]:https://github.com/switchbrew
-[@fincs]:https://github.com/fincs
-[@cpasjuste]:https://github.com/Cpasjuste
-[@fhidalgosola]:https://github.com/fhidalgosola
-
-[@VitaSDK]:https://github.com/VitaSDK
-[VitaSDK]:https://vitasdk.org
diff --git a/README-switch.md b/README-switch.md
new file mode 100644
index 000000000000..2a6025c9daff
--- /dev/null
+++ b/README-switch.md
@@ -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.
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 0943a127d053..932ce56f7ee6 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -86,18 +86,10 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
- ClassDB::bind_method(D_METHOD("get_joy_gravity", "device"), &Input::get_joy_gravity);
- ClassDB::bind_method(D_METHOD("get_joy_accelerometer", "device"), &Input::get_joy_accelerometer);
- ClassDB::bind_method(D_METHOD("get_joy_magnetometer", "device"), &Input::get_joy_magnetometer);
- ClassDB::bind_method(D_METHOD("get_joy_gyroscope", "device"), &Input::get_joy_gyroscope);
ClassDB::bind_method(D_METHOD("set_gravity", "value"), &Input::set_gravity);
ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
- ClassDB::bind_method(D_METHOD("set_joy_gravity", "device", "value"), &Input::set_joy_gravity);
- ClassDB::bind_method(D_METHOD("set_joy_accelerometer", "device", "value"), &Input::set_joy_accelerometer);
- ClassDB::bind_method(D_METHOD("set_joy_magnetometer", "device", "value"), &Input::set_joy_magnetometer);
- ClassDB::bind_method(D_METHOD("set_joy_gyroscope", "device", "value"), &Input::set_joy_gyroscope);
//ClassDB::bind_method(D_METHOD("get_mouse_position"),&Input::get_mouse_position); - this is not the function you want
ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed);
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
diff --git a/core/os/input.h b/core/os/input.h
index b6a2cafcc8ad..f6ae3e57b6b8 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -117,18 +117,10 @@ class Input : public Object {
virtual Vector3 get_accelerometer() const = 0;
virtual Vector3 get_magnetometer() const = 0;
virtual Vector3 get_gyroscope() const = 0;
- virtual Vector3 get_joy_gravity(int p_device) const = 0;
- virtual Vector3 get_joy_accelerometer(int p_device) const = 0;
- virtual Vector3 get_joy_magnetometer(int p_device) const = 0;
- virtual Vector3 get_joy_gyroscope(int p_device) const = 0;
virtual void set_gravity(const Vector3 &p_gravity) = 0;
virtual void set_accelerometer(const Vector3 &p_accel) = 0;
virtual void set_magnetometer(const Vector3 &p_magnetometer) = 0;
virtual void set_gyroscope(const Vector3 &p_gyroscope) = 0;
- virtual void set_joy_gravity(int p_device, const Vector3 &p_gravity) = 0;
- virtual void set_joy_accelerometer(int p_device, const Vector3 &p_accel) = 0;
- virtual void set_joy_magnetometer(int p_device, const Vector3 &p_magnetometer) = 0;
- virtual void set_joy_gyroscope(int p_device, const Vector3 &p_gyroscope) = 0;
virtual void action_press(const StringName &p_action, float p_strength = 1.f) = 0;
virtual void action_release(const StringName &p_action) = 0;
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index ad46fcedd866..1d51658a026d 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -62,10 +62,6 @@
The [NavigationServer] singleton.
-
- The [NintendoSwitch] singleton.
- [b]Note:[/b] Only implemented on Nintendo Switch.
-
The [OS] singleton.
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index e1f94db3988f..70a3baa77c4e 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -105,13 +105,6 @@
[b]Note:[/b] This method only works on Android and iOS. On other platforms, it always returns [constant Vector3.ZERO].
-
-
-
-
- Returns the acceleration of the controller's accelerometer sensor, if the controller has one. Otherwise, the method returns [constant Vector3.ZERO].
-
-
@@ -148,13 +141,6 @@
Receives a gamepad button from [enum JoystickList] and returns its equivalent name as a string.
-
-
-
-
- Returns the gravity of the controller's accelerometer sensor, if the controller has one. Otherwise, the method returns [constant Vector3.ZERO].
-
-
@@ -162,20 +148,6 @@
Returns a SDL2-compatible device GUID on platforms that use gamepad remapping, e.g. [code]030000004c050000c405000000010000[/code]. Returns [code]"Default Gamepad"[/code] otherwise. Godot uses the [url=https://github.com/gabomdq/SDL_GameControllerDB]SDL2 game controller database[/url] to determine gamepad names and mappings based on this GUID.
-
-
-
-
- Returns the rotation rate in rad/s around a controller's X, Y, and Z axes of the gyroscope sensor, if the controller has one. Otherwise, the method returns [constant Vector3.ZERO].
-
-
-
-
-
-
- Returns the magnetic field strength in micro-Tesla for all axes of the controller's magnetometer sensor, if the controller has one. Otherwise, the method returns [constant Vector3.ZERO].
-
-
@@ -374,53 +346,15 @@
- Sets the value of the rotation rate of the device's gyroscope sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
+ Sets the value of the rotation rate of the gyroscope sensor. Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
[b]Note:[/b] This value can be immediately overwritten by the hardware sensor value on Android and iOS.
-
-
-
-
-
- Sets the acceleration value of the controller's accelerometer sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
-
-
-
-
-
-
-
- Sets the gravity value of the controller's accelerometer sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
-
-
-
-
-
-
-
- Sets the value of the rotation rate of the controller's gyroscope sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
-
-
-
-
-
-
-
- Sets the value of the magnetic field of the controller's magnetometer sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
-
-
- Sets the value of the magnetic field of the device's magnetometer sensor.
- Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
+ Sets the value of the magnetic field of the magnetometer sensor. Can be used for debugging on devices without a hardware sensor, for example in an editor on a PC.
[b]Note:[/b] This value can be immediately overwritten by the hardware sensor value on Android and iOS.
diff --git a/doc/classes/NintendoSwitch.xml b/doc/classes/NintendoSwitch.xml
deleted file mode 100644
index d2b44f684f3c..000000000000
--- a/doc/classes/NintendoSwitch.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
- Singleton that adds new functions specific to Nintendo Switch's Horizon OS.
-
-
- The NintendoSwitch singleton is implemented only in the Nintendo Switch export. It's used to access features that are only supported by Horizon OS.
-
-
-
-
-
-
-
-
-
- Shows the virtual keyboard of the type specified.
- The [code]existing_text[/code] parameter is useful for implementing your own [LineEdit] or [TextEdit], as it tells the virtual keyboard what text has already been typed.
-
-
-
-
-
- Normal keyboard.
-
-
- Number pad.
-
-
- QWERTY (and variants) keyboard only.
-
-
- All Latin like languages keyboard only (without CJK keyboard).
-
-
- Chinese Simplified keyboard only.
-
-
- Chinese Traditional keyboard only.
-
-
- Korean keyboard only.
-
-
- All language keyboards.
-
-
-
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 8404972b4967..10b53e76c74d 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -1019,7 +1019,7 @@
Shows the virtual keyboard if the platform has one.
The [code]existing_text[/code] parameter is useful for implementing your own [LineEdit] or [TextEdit], as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions).
The [code]multiline[/code] parameter needs to be set to [code]true[/code] to be able to enter multiple lines of text, as in [TextEdit].
- [b]Note:[/b] This method is implemented on Android, iOS, UWP, Nintendo Switch, and PlayStation Vita.
+ [b]Note:[/b] This method is implemented on Android, iOS and UWP.
diff --git a/drivers/SCsub b/drivers/SCsub
index 36c5bb909462..890877981874 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -10,8 +10,6 @@ SConscript("windows/SCsub")
# Sounds drivers
SConscript("alsa/SCsub")
-if env["platform"] == "switch":
- SConscript("audren/SCsub")
SConscript("coreaudio/SCsub")
SConscript("pulseaudio/SCsub")
if env["platform"] == "windows":
diff --git a/drivers/audren/SCsub b/drivers/audren/SCsub
deleted file mode 100644
index 783e725ea283..000000000000
--- a/drivers/audren/SCsub
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-# Driver source files
-env.add_source_files(env.drivers_sources, "audio_driver_audren.cpp")
diff --git a/drivers/audren/audio_driver_audren.cpp b/drivers/audren/audio_driver_audren.cpp
deleted file mode 100644
index 6a53251d4e57..000000000000
--- a/drivers/audren/audio_driver_audren.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/**************************************************************************/
-/* audio_driver_audren.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "audio_driver_audren.h"
-
-#include "core/os/os.h"
-#include "core/project_settings.h"
-
-#include
-#include
-
-static const AudioRendererConfig arConfig = {
- .output_rate = AudioRendererOutputRate_48kHz,
- .num_voices = 24,
- .num_effects = 0,
- .num_sinks = 1,
- .num_mix_objs = 1,
- .num_mix_buffers = 2,
-};
-
-Error AudioDriverAudren::init_device() {
- int latency = GLOBAL_GET("audio/output_latency");
- mix_rate = GLOBAL_GET("audio/mix_rate");
- channels = 2;
- speaker_mode = SPEAKER_MODE_STEREO;
- buffer_size = closest_power_of_2(latency * mix_rate / 1000);
- samples_in.resize(buffer_size * channels);
- samples_out.resize(buffer_size * channels);
-
- Result res = audrenInitialize(&arConfig);
- printf("audrenInitialize: %x\n", res);
- res = audrvCreate(&audren_driver, &arConfig, 2);
- printf("audrenInitialize: %x\n", res);
-
- audren_buffer_size = (sizeof(int16_t) * buffer_size * channels);
- audren_pool_size = ((audren_buffer_size * 2) + 0xFFF) & ~0xFFF;
- audren_pool_ptr = memalign(0x1000, audren_pool_size);
-
- for (int i = 0; i < 2; i++) {
- audren_buffers[i] = { 0 };
- audren_buffers[i].data_raw = audren_pool_ptr;
- audren_buffers[i].size = audren_buffer_size * 2;
- audren_buffers[i].start_sample_offset = i * buffer_size;
- audren_buffers[i].end_sample_offset = audren_buffers[i].start_sample_offset + buffer_size;
- }
-
- int mpid = audrvMemPoolAdd(&audren_driver, audren_pool_ptr, audren_pool_size);
- audrvMemPoolAttach(&audren_driver, mpid);
-
- static const u8 sink_channels[] = { 0, 1 };
- audrvDeviceSinkAdd(&audren_driver, AUDREN_DEFAULT_DEVICE_NAME, 2, sink_channels);
-
- res = audrvUpdate(&audren_driver);
- printf("audrvUpdate: %x\n", res);
-
- res = audrenStartAudioRenderer();
- printf("audrenStartAudioRenderer: %x\n", res);
-
- audrvVoiceInit(&audren_driver, 0, channels, PcmFormat_Int16, mix_rate);
- audrvVoiceSetDestinationMix(&audren_driver, 0, AUDREN_FINAL_MIX_ID);
- if (channels == 1) {
- audrvVoiceSetMixFactor(&audren_driver, 0, 1.0f, 0, 0);
- audrvVoiceSetMixFactor(&audren_driver, 0, 1.0f, 0, 1);
- } else {
- audrvVoiceSetMixFactor(&audren_driver, 0, 1.0f, 0, 0);
- audrvVoiceSetMixFactor(&audren_driver, 0, 0.0f, 0, 1);
- audrvVoiceSetMixFactor(&audren_driver, 0, 0.0f, 1, 0);
- audrvVoiceSetMixFactor(&audren_driver, 0, 1.0f, 1, 1);
- }
-
- return OK;
-}
-
-Error AudioDriverAudren::init() {
- active = false;
- thread_exited = false;
- exit_thread = false;
-
- Error err = init_device();
- if (err == OK) {
- thread.start(AudioDriverAudren::thread_func, this);
- }
-
- return err;
-}
-
-void AudioDriverAudren::thread_func(void *p_udata) {
- AudioDriverAudren *ad = (AudioDriverAudren *)p_udata;
-
- svcSetThreadPriority(CUR_THREAD_HANDLE, 0x2B);
-
- while (!ad->exit_thread) {
- ad->lock();
- ad->start_counting_ticks();
-
- if (!ad->active) {
- for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
- ad->samples_out.write[i] = 0;
- }
- } else {
- ad->audio_server_process(ad->buffer_size, ad->samples_in.ptrw());
- for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
- ad->samples_out.write[i] = ad->samples_in[i] >> 16;
- }
- }
-
- int free_buffer = -1;
- for (int i = 0; i < 2; i++) {
- if (ad->audren_buffers[i].state == AudioDriverWaveBufState_Free || ad->audren_buffers[i].state == AudioDriverWaveBufState_Done) {
- free_buffer = i;
- break;
- }
- }
-
- if (free_buffer >= 0) {
- uint8_t *ptr = (uint8_t *)ad->audren_pool_ptr + (free_buffer * ad->audren_buffer_size);
- memcpy(ptr, ad->samples_out.ptr(), ad->audren_buffer_size);
- armDCacheFlush(ptr, ad->audren_buffer_size);
- audrvVoiceAddWaveBuf(&ad->audren_driver, 0, &ad->audren_buffers[free_buffer]);
- if (!audrvVoiceIsPlaying(&ad->audren_driver, 0)) {
- audrvVoiceStart(&ad->audren_driver, 0);
- }
- audrvUpdate(&ad->audren_driver);
- audrenWaitFrame();
- while (ad->audren_buffers[free_buffer].state != AudioDriverWaveBufState_Playing) {
- audrvUpdate(&ad->audren_driver);
- }
- } else {
- //printf("aud: no free buffer\n");
- ad->stop_counting_ticks();
- ad->unlock();
- OS::get_singleton()->delay_usec(1000);
- ad->lock();
- ad->start_counting_ticks();
- }
-
- ad->stop_counting_ticks();
- ad->unlock();
- }
-
- ad->thread_exited = true;
-}
-
-void AudioDriverAudren::start() {
- active = true;
-}
-
-int AudioDriverAudren::get_mix_rate() const {
- return mix_rate;
-}
-
-AudioDriver::SpeakerMode AudioDriverAudren::get_speaker_mode() const {
- return speaker_mode;
-}
-
-Array AudioDriverAudren::get_device_list() {
- Array list;
- list.push_back("Default");
- return list;
-}
-
-String AudioDriverAudren::get_device() {
- return device_name;
-}
-
-void AudioDriverAudren::set_device(String device) {
- lock();
- new_device = device;
- unlock();
-}
-
-void AudioDriverAudren::lock() {
- mutex.lock();
-}
-
-void AudioDriverAudren::unlock() {
- mutex.unlock();
-}
-
-void AudioDriverAudren::finish() {
- exit_thread = true;
- thread.wait_to_finish();
-
- audrvClose(&audren_driver);
- audrenExit();
-}
-
-AudioDriverAudren::AudioDriverAudren() :
- device_name("Default"),
- new_device("Default") {
-}
-
-AudioDriverAudren::~AudioDriverAudren() {
-}
diff --git a/drivers/audren/audio_driver_audren.h b/drivers/audren/audio_driver_audren.h
deleted file mode 100644
index c0604b8c120a..000000000000
--- a/drivers/audren/audio_driver_audren.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/**************************************************************************/
-/* audio_driver_audren.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#pragma once
-#ifndef AUDIO_DRIVER_AUDREN_H
-#define AUDIO_DRIVER_AUDREN_H
-
-#include "servers/audio_server.h"
-#include "switch_wrapper.h"
-
-#include "core/os/mutex.h"
-#include "core/os/thread.h"
-
-class AudioDriverAudren : public AudioDriver {
- Thread thread;
- Mutex mutex;
-
- LibnxAudioDriver audren_driver;
- AudioDriverWaveBuf audren_buffers[2];
- size_t audren_pool_size;
- void *audren_pool_ptr;
- unsigned int audren_buffer_size;
- unsigned int buffer_size;
- Vector samples_in;
- Vector samples_out;
-
- String device_name;
- String new_device;
-
- Error init_device();
- void finish_device();
-
- static void thread_func(void *p_udata);
-
- unsigned int mix_rate;
- SpeakerMode speaker_mode;
- int channels;
-
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
-
-public:
- const char *get_name() const {
- return "AUDREN";
- };
-
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual Array get_device_list();
- virtual String get_device();
- virtual void set_device(String device);
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- AudioDriverAudren();
- ~AudioDriverAudren();
-};
-
-#endif // !AUDIO_DRIVER_AUDREN_H
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 4ce3ab687ec3..8a0635c5f44c 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -205,26 +205,6 @@ float InputDefault::get_joy_axis(int p_device, int p_axis) const {
}
}
-Vector3 InputDefault::get_joy_gravity(int p_device) const {
- _THREAD_SAFE_METHOD_
- return gravity;
-}
-
-Vector3 InputDefault::get_joy_accelerometer(int p_device) const {
- _THREAD_SAFE_METHOD_
- return accelerometer;
-}
-
-Vector3 InputDefault::get_joy_magnetometer(int p_device) const {
- _THREAD_SAFE_METHOD_
- return magnetometer;
-}
-
-Vector3 InputDefault::get_joy_gyroscope(int p_device) const {
- _THREAD_SAFE_METHOD_
- return gyroscope;
-}
-
String InputDefault::get_joy_name(int p_idx) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx].name;
@@ -519,30 +499,6 @@ void InputDefault::set_joy_axis(int p_device, int p_axis, float p_value) {
_joy_axis[c] = p_value;
}
-void InputDefault::set_joy_gravity(int p_device, const Vector3 &p_gravity) {
- _THREAD_SAFE_METHOD_
-
- gravity = p_gravity;
-}
-
-void InputDefault::set_joy_accelerometer(int p_device, const Vector3 &p_accel) {
- _THREAD_SAFE_METHOD_
-
- accelerometer = p_accel;
-}
-
-void InputDefault::set_joy_magnetometer(int p_device, const Vector3 &p_magnetometer) {
- _THREAD_SAFE_METHOD_
-
- magnetometer = p_magnetometer;
-}
-
-void InputDefault::set_joy_gyroscope(int p_device, const Vector3 &p_gyroscope) {
- _THREAD_SAFE_METHOD_
-
- gyroscope = p_gyroscope;
-}
-
void InputDefault::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
_THREAD_SAFE_METHOD_
if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {
diff --git a/main/input_default.h b/main/input_default.h
index aa6e1677d051..00905ac19db4 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -226,10 +226,6 @@ class InputDefault : public Input {
virtual float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const;
virtual float get_joy_axis(int p_device, int p_axis) const;
- virtual Vector3 get_joy_gravity(int p_device) const;
- virtual Vector3 get_joy_accelerometer(int p_device) const;
- virtual Vector3 get_joy_magnetometer(int p_device) const;
- virtual Vector3 get_joy_gyroscope(int p_device) const;
String get_joy_name(int p_idx);
virtual Array get_connected_joypads();
virtual Vector2 get_joy_vibration_strength(int p_device);
@@ -256,10 +252,6 @@ class InputDefault : public Input {
virtual void set_magnetometer(const Vector3 &p_magnetometer);
virtual void set_gyroscope(const Vector3 &p_gyroscope);
void set_joy_axis(int p_device, int p_axis, float p_value);
- virtual void set_joy_gravity(int p_device, const Vector3 &p_gravity);
- virtual void set_joy_accelerometer(int p_device, const Vector3 &p_accel);
- virtual void set_joy_magnetometer(int p_device, const Vector3 &p_magnetometer);
- virtual void set_joy_gyroscope(int p_device, const Vector3 &p_gyroscope);
virtual void start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration = 0);
virtual void stop_joy_vibration(int p_device);
diff --git a/platform/switch/SCsub b/platform/switch/SCsub
index e190389ec04d..83fad068a4ef 100644
--- a/platform/switch/SCsub
+++ b/platform/switch/SCsub
@@ -7,7 +7,9 @@ Import("env")
files = [
"godot_switch.cpp",
"os_switch.cpp",
+ "power_switch.cpp",
"joypad_switch.cpp",
+ "audio_driver_switch.cpp",
"context_gl_switch_egl.cpp",
]
diff --git a/platform/switch/api/api.cpp b/platform/switch/api/api.cpp
deleted file mode 100644
index ca6a8fe4e9a4..000000000000
--- a/platform/switch/api/api.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/**************************************************************************/
-/* api.cpp */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#include "api.h"
-#ifdef HORIZON_ENABLED
-#include "os_switch.h"
-#endif // HORIZON_ENABLED
-#include "switch_singleton.h"
-
-#include "core/engine.h"
-#include "core/os/keyboard.h"
-
-// === === ===
-// === API ===
-// === === ===
-
-static NintendoSwitch *switch_eval;
-
-void register_switch_api() {
- ClassDB::register_virtual_class();
- switch_eval = memnew(NintendoSwitch);
- Engine::get_singleton()->add_singleton(Engine::Singleton("NintendoSwitch", switch_eval));
-}
-
-void unregister_switch_api() {
- memdelete(switch_eval);
-}
-
-// === === === === === === === === ===
-// === Nintendo Switch Singleton ===
-// === === === === === === === === ===
-
-bool g_swkbd_open = false;
-
-NintendoSwitch *NintendoSwitch::singleton = nullptr;
-
-NintendoSwitch *NintendoSwitch::get_singleton() {
- return singleton;
-}
-
-NintendoSwitch::NintendoSwitch() {
- ERR_FAIL_COND_MSG(singleton != nullptr, "NintendoSwitch singleton already exists.");
- singleton = this;
-#ifdef HORIZON_ENABLED
- swkbdInlineCreate(&inline_keyboard);
-#endif // HORIZON_ENABLED
-}
-
-void NintendoSwitch::_bind_methods() {
- ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text", "type"), &NintendoSwitch::show_virtual_keyboard, DEFVAL(""), DEFVAL(NORMAL_KEYBOARD));
-
- BIND_ENUM_CONSTANT(NORMAL_KEYBOARD)
- BIND_ENUM_CONSTANT(NUMPAD_KEYBOARD)
- BIND_ENUM_CONSTANT(QWERTY_KEYBOARD)
- BIND_ENUM_CONSTANT(LATIN_KEYBOARD)
- BIND_ENUM_CONSTANT(SIMPLIFIED_CHINESE_KEYBOARD)
- BIND_ENUM_CONSTANT(TRADITIONAL_CHINESE_KEYBOARD)
- BIND_ENUM_CONSTANT(KOREAN_KEYBOARD)
- BIND_ENUM_CONSTANT(ALL_LANGUAGES_KEYBOARD)
-}
-
-#ifdef HORIZON_ENABLED
-int g_eat_string_events = 0;
-
-u32 last_length = 0;
-void keyboard_string_changed_callback(const char *str, SwkbdChangedStringArg *arg) {
- // Adjusted for NUL-terminator
- u32 string_length = arg->stringLen + 3;
-
- // We get a string changed event on appear, and another one on setting text.
- if (g_eat_string_events) {
- last_length = string_length;
- g_eat_string_events--;
- return;
- }
-
- if (string_length < last_length) {
- OS_Switch::get_singleton()->key(KEY_BACKSPACE, true);
- } else if (string_length > 0) {
- OS_Switch::get_singleton()->key(str[string_length - 1], true);
- }
- last_length = string_length;
-}
-
-int last_cursor = 0;
-void keyboard_moved_cursor_callback(const char *str, SwkbdMovedCursorArg *arg) {
- if (arg->cursorPos < last_cursor) {
- OS_Switch::get_singleton()->key(KEY_LEFT, true);
- } else {
- OS_Switch::get_singleton()->key(KEY_RIGHT, true);
- }
-
- last_cursor = arg->cursorPos;
-}
-
-void keyboard_decided_enter_callback(const char *str, SwkbdDecidedEnterArg *arg) {
- OS_Switch::get_singleton()->key(KEY_ENTER, true);
-
- g_swkbd_open = false;
-}
-
-void keyboard_decided_cancel_callback() {
- g_swkbd_open = false;
-}
-#endif // HORIZON_ENABLED
-
-void NintendoSwitch::initialize_software_keyboard() {
-#ifdef HORIZON_ENABLED
- swkbdInlineLaunchForLibraryApplet(&inline_keyboard, SwkbdInlineMode_AppletDisplay, 0);
- swkbdInlineSetChangedStringCallback(&inline_keyboard, keyboard_string_changed_callback);
- swkbdInlineSetMovedCursorCallback(&inline_keyboard, keyboard_moved_cursor_callback);
- swkbdInlineSetDecidedEnterCallback(&inline_keyboard, keyboard_decided_enter_callback);
- swkbdInlineSetDecidedCancelCallback(&inline_keyboard, keyboard_decided_cancel_callback);
-#endif // HORIZON_ENABLED
-}
-
-void NintendoSwitch::update() {
-#ifdef HORIZON_ENABLED
- swkbdInlineUpdate(&inline_keyboard, NULL);
-#endif // HORIZON_ENABLED
-}
-
-void NintendoSwitch::show_virtual_keyboard(const String &p_existing_text, SoftwareKeyboardType p_type) {
-#ifdef HORIZON_ENABLED
- if (!g_swkbd_open) {
- SwkbdAppearArg appear_arg;
- swkbdInlineMakeAppearArg(&appear_arg, (SwkbdType)p_type);
- swkbdInlineSetInputText(&inline_keyboard, p_existing_text.utf8().get_data());
- swkbdInlineSetCursorPos(&inline_keyboard, p_existing_text.size() - 1);
-
- swkbdInlineAppear(&inline_keyboard, &appear_arg);
-
- g_eat_string_events = 2;
- g_swkbd_open = true;
- }
-#endif // HORIZON_ENABLED
-}
-
-void NintendoSwitch::hide_virtual_keyboard() {
-#ifdef HORIZON_ENABLED
- swkbdInlineDisappear(&inline_keyboard);
- g_swkbd_open = false;
-#endif // HORIZON_ENABLED
-}
-
-bool NintendoSwitch::is_virtual_keyboard_open() {
- return g_swkbd_open;
-}
-
-void NintendoSwitch::cleanup() {
-#ifdef HORIZON_ENABLED
- swkbdInlineClose(&inline_keyboard);
-#endif // HORIZON_ENABLED
-}
diff --git a/platform/switch/api/api.h b/platform/switch/api/api.h
deleted file mode 100644
index 065a2448300e..000000000000
--- a/platform/switch/api/api.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**************************************************************************/
-/* api.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef SWITCH_API_H
-#define SWITCH_API_H
-
-#ifndef MODULE_MONO_ENABLED
-
-void register_switch_api();
-void unregister_switch_api();
-
-#endif // MODULE_MONO_ENABLED`
-
-#endif // SWITCH_API_H
diff --git a/platform/switch/api/switch_singleton.h b/platform/switch/api/switch_singleton.h
deleted file mode 100644
index dcf1a6dfbc1c..000000000000
--- a/platform/switch/api/switch_singleton.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************/
-/* switch_singleton.h */
-/**************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/**************************************************************************/
-
-#ifndef SWITCH_SINGLETON_H
-#define SWITCH_SINGLETON_H
-
-#ifndef MODULE_MONO_ENABLED
-
-#include "core/object.h"
-#include "core/variant.h"
-#ifdef HORIZON_ENABLED
-#include "switch_wrapper.h"
-#endif // HORIZON_ENABLED
-
-class NintendoSwitch : public Object {
- GDCLASS(NintendoSwitch, Object);
-
-public:
- enum SoftwareKeyboardType {
- NORMAL_KEYBOARD = 0,
- NUMPAD_KEYBOARD = 1,
- QWERTY_KEYBOARD = 2,
- LATIN_KEYBOARD = 4,
- SIMPLIFIED_CHINESE_KEYBOARD = 5,
- TRADITIONAL_CHINESE_KEYBOARD = 6,
- KOREAN_KEYBOARD = 7,
- ALL_LANGUAGES_KEYBOARD = 8,
- };
-
- int g_eat_string_events = 0;
-#ifdef HORIZON_ENABLED
- SwkbdInline inline_keyboard;
-#endif // HORIZON_ENABLED
-
-protected:
- static NintendoSwitch *singleton;
-
- static void _bind_methods();
-
-public:
- static NintendoSwitch *get_singleton();
-
- void initialize_software_keyboard();
- void update();
- void show_virtual_keyboard(const String &p_existing_text, SoftwareKeyboardType p_type);
- void hide_virtual_keyboard();
- bool is_virtual_keyboard_open();
-
- void cleanup();
-
- NintendoSwitch();
-};
-
-VARIANT_ENUM_CAST(NintendoSwitch::SoftwareKeyboardType);
-
-#endif // MODULE_MONO_ENABLED
-
-#endif // SWITCH_SINGLETON_H
diff --git a/platform/switch/export/export.cpp b/platform/switch/export/export.cpp
index 6673d0c17f03..9a275a638f2f 100644
--- a/platform/switch/export/export.cpp
+++ b/platform/switch/export/export.cpp
@@ -36,14 +36,93 @@
#include "core/io/packet_peer_udp.h"
#include "core/os/file_access.h"
+#include "core/os/thread.h"
+#include "core/os/mutex.h"
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "platform/switch/logo.gen.h"
#include "scene/resources/texture.h"
+#ifdef WINDOWS_ENABLED
+#include
+#include
+#endif
+
#define TEMPLATE_RELEASE "switch_release.nro"
#define TEMPLATE_APPLET_SPLASH "switch_applet_splash.rgba.gz"
+// NXLink output streaming using proper stdout capture
+class NXLinkStreamThread {
+private:
+ Thread thread;
+ Mutex mutex;
+ bool running;
+ String nxlink_path;
+ List nxlink_args;
+ String tmp_pack_path; // Store the path to clean up later
+
+public:
+ NXLinkStreamThread() : running(false) {}
+
+ void start(const String &p_nxlink_path, const List &p_args, const String &p_tmp_pack_path) {
+ if (running) return;
+
+ nxlink_path = p_nxlink_path;
+ nxlink_args = p_args;
+ tmp_pack_path = p_tmp_pack_path;
+ running = true;
+ thread.start(_thread_function, this);
+ }
+
+ void stop() {
+ if (!running) return;
+
+ running = false;
+ thread.wait_to_finish();
+ }
+
+ bool is_running() const { return running; }
+
+private:
+ static void _thread_function(void *p_userdata) {
+ NXLinkStreamThread *self = (NXLinkStreamThread *)p_userdata;
+ self->_run();
+ }
+
+ void _run() {
+ // Build the nxlink command string
+ String command = nxlink_path;
+ for (List::Element *E = nxlink_args.front(); E; E = E->next()) {
+ command += " " + E->get();
+ }
+
+ print_line("Executing nxlink with real-time output capture...");
+ print_line("NXLink command: " + command);
+
+ // Run nxlink directly without capturing output to avoid UI issues
+ // This will open a separate console window like command prompt
+ print_line("Starting nxlink in separate console window...");
+ print_line("Check the new console window for nxlink output");
+
+ // Use start command to open nxlink in a new console window
+ String start_command = "start " + command;
+ int result = system(start_command.utf8().ptr());
+
+ // Wait a moment for the console to open
+ OS::get_singleton()->delay_usec(1000000); // 1 second
+
+ print_line("nxlink started in separate console window");
+
+ // Clean up the temporary file
+ if (!tmp_pack_path.empty()) {
+ DirAccess::remove_file_or_error(tmp_pack_path);
+ print_line("Cleaned up temporary export file");
+ }
+
+ print_line("=== NXLINK PROCESS COMPLETED ===");
+ }
+};
+
class ExportPluginSwitch : public EditorExportPlugin {
public:
Vector editor_id_vec;
@@ -68,6 +147,7 @@ class EditorExportPlatformSwitch : public EditorExportPlatform {
volatile bool quit_request;
ExportPluginSwitch *export_plugin;
+ NXLinkStreamThread *nxlink_thread;
static void _device_poll_thread(void *ud) {
EditorExportPlatformSwitch *ea = (EditorExportPlatformSwitch *)ud;
@@ -223,18 +303,27 @@ class EditorExportPlatformSwitch : public EditorExportPlatform {
return ERR_SKIP;
}
- String tmp_pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.pck");
+ // Export the full .nro file instead of just a .pck
+ String tmp_nro_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.nro");
- Error err = save_pack(p_preset, tmp_pack_path);
+ Error err = export_project(p_preset, true, tmp_nro_path, p_debug_flags);
if (err != OK) {
- DirAccess::remove_file_or_error(tmp_pack_path);
+ DirAccess::remove_file_or_error(tmp_nro_path);
return err;
}
+
+ // Verify the .nro file was created
+ if (!FileAccess::exists(tmp_nro_path)) {
+ print_line("ERROR: .nro file was not created at: " + tmp_nro_path);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ print_line("Successfully created .nro file: " + tmp_nro_path);
print_line("Sending...");
if (ep.step("Sending...", 1)) {
- DirAccess::remove_file_or_error(tmp_pack_path);
+ DirAccess::remove_file_or_error(tmp_nro_path);
return err;
}
@@ -249,29 +338,41 @@ class EditorExportPlatformSwitch : public EditorExportPlatform {
}
if (FileAccess::exists(nxlink)) {
+ // Check if nxlink is already running
+ if (nxlink_thread && nxlink_thread->is_running()) {
+ print_line("NXLink is already running. Please wait for the current session to end.");
+ return OK;
+ }
+
List args;
int ec;
-
- args.push_back(tmp_pack_path);
- args.push_back("-a");
- args.push_back(devices[p_device]);
- args.push_back("-p");
- args.push_back("TempExport.pck");
- args.push_back("--args");
-
- Vector inner_args;
- // todo: editor arg
- inner_args.push_back("-v");
-
- gen_export_flags(inner_args, p_debug_flags);
- args.push_back(String(" ").join(inner_args));
-
- OS::get_singleton()->execute(nxlink, args, true, NULL, NULL, &ec);
+ String pipe_output;
+
+ args.push_back("-s"); // Enable server mode for real-time debugging
+ args.push_back(tmp_nro_path);
+
+ // Game arguments are not needed for nxlink - they're passed to the game itself
+ // nxlink just needs the -s flag and the nro file path
+
+ // Create and start nxlink streaming thread
+ nxlink_thread = memnew(NXLinkStreamThread);
+ print_line("Starting nxlink with remote debugging...");
+ print_line("=== NXLINK OUTPUT ===");
+
+ nxlink_thread->start(nxlink, args, tmp_nro_path);
+
+ // Give nxlink a moment to start
+ OS::get_singleton()->delay_usec(2000000); // 2 seconds
+
+ print_line("=== NXLINK STREAMING STARTED ===");
+ print_line("Real-time debug output will appear below as the game runs on Switch.");
+ print_line("The nxlink stream will continue until the game exits or you close Godot.");
} else {
EditorNode::get_singleton()->show_warning(TTR("nxlink binary not found! Set its path in Editor Settings."));
}
- DirAccess::remove_file_or_error(tmp_pack_path);
+ // Don't remove the file immediately - let nxlink use it
+ // The file will be cleaned up when the thread ends
return OK;
}
@@ -568,12 +669,19 @@ class EditorExportPlatformSwitch : public EditorExportPlatform {
export_plugin = memnew(ExportPluginSwitch);
EditorExport::get_singleton()->add_export_plugin(export_plugin);
+ nxlink_thread = nullptr;
}
~EditorExportPlatformSwitch() {
quit_request = true;
device_thread.wait_to_finish();
+ // Stop nxlink thread if running
+ if (nxlink_thread && nxlink_thread->is_running()) {
+ nxlink_thread->stop();
+ memdelete(nxlink_thread);
+ }
+
// DO NOT free it
//memdelete(export_plugin);
}
diff --git a/platform/switch/export/export.h b/platform/switch/export/export.h
index 88d2799df9ee..288ca0ad1064 100644
--- a/platform/switch/export/export.h
+++ b/platform/switch/export/export.h
@@ -28,11 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef SWITCH_EXPORT_H
-#define SWITCH_EXPORT_H
-
-#ifndef MODULE_MONO_ENABLED
-
#include "thirdparty/libnx/nacp.h"
#include "thirdparty/libnx/nro.h"
#include
@@ -43,7 +38,3 @@ unsigned char *read_bytes(const char *fn, size_t off, size_t len);
size_t write_bytes(const char *fn, size_t off, size_t len, const unsigned char *data);
void register_switch_exporter();
-
-#endif // !MODULE_MONO_ENABLED
-
-#endif // !SWITCH_EXPORT_H
diff --git a/platform/switch/os_switch.cpp b/platform/switch/os_switch.cpp
index 554a90df8534..917e3ee1e6c6 100644
--- a/platform/switch/os_switch.cpp
+++ b/platform/switch/os_switch.cpp
@@ -77,13 +77,13 @@ void OS_Switch::initialize_core() {
}
void OS_Switch::swap_buffers() {
-#ifdef OPENGL_ENABLED
+#if defined(OPENGL_ENABLED)
gl_context->swap_buffers();
#endif
}
Error OS_Switch::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-#ifdef OPENGL_ENABLED
+#if defined(OPENGL_ENABLED)
bool gles3_context = true;
if (p_video_driver == VIDEO_DRIVER_GLES2) {
gles3_context = false;
@@ -144,8 +144,8 @@ Error OS_Switch::initialize(const VideoMode &p_desired, int p_video_driver, int
}
if (gl_initialization_error) {
- OS::get_singleton()->alert("Your firmware does not support any of the supported OpenGL versions.\n"
- "Please update your custom firmware to install the latest OpenGL driver.",
+ OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
+ "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
"Unable to initialize Video driver");
return ERR_UNAVAILABLE;
}
@@ -170,12 +170,12 @@ Error OS_Switch::initialize(const VideoMode &p_desired, int p_video_driver, int
}
joypad = memnew(JoypadSwitch(input));
- if (R_SUCCEEDED(psmInitialize())) {
- OS_Switch::psm_initialized = true;
- }
+ power_manager = memnew(PowerSwitch);
AudioDriverManager::initialize(p_audio_driver);
+ //_ensure_user_data_dir();
+
return OK;
}
@@ -191,14 +191,12 @@ void OS_Switch::delete_main_loop() {
}
void OS_Switch::finalize() {
- NintendoSwitch::get_singleton()->cleanup();
-
memdelete(input);
memdelete(joypad);
visual_server->finish();
memdelete(visual_server);
+ memdelete(power_manager);
memdelete(gl_context);
- psmExit();
}
void OS_Switch::finalize_core() {
@@ -209,16 +207,11 @@ bool OS_Switch::_check_internal_feature_support(const String &p_feature) {
//TODO support etc2 only if GLES3 driver is selected
return true;
}
- if (p_feature == "arm64-v8a") {
- return true;
- }
return false;
}
void OS_Switch::alert(const String &p_alert, const String &p_title) {
- ErrorApplicationConfig config;
- errorApplicationCreate(&config, p_title.utf8().ptr(), p_alert.utf8().ptr());
- errorApplicationShow(&config);
+ printf("got alert %ls", p_alert.c_str());
}
String OS_Switch::get_stdin_string(bool p_block) {
return "";
@@ -308,72 +301,16 @@ MainLoop *OS_Switch::get_main_loop() const {
return main_loop;
}
-/// From os_unix.cpp
-OS::Date OS_Switch::get_date(bool utc) const {
- time_t t = time(nullptr);
- struct tm lt;
- if (utc) {
- gmtime_r(&t, <);
- } else {
- localtime_r(&t, <);
- }
- Date ret;
- ret.year = 1900 + lt.tm_year;
- // Index starting at 1 to match OS_Unix::get_date
- // and Windows SYSTEMTIME and tm_mon follows the typical structure
- // of 0-11, noted here: http://www.cplusplus.com/reference/ctime/tm/
- ret.month = (Month)(lt.tm_mon + 1);
- ret.day = lt.tm_mday;
- ret.weekday = (Weekday)lt.tm_wday;
- ret.dst = lt.tm_isdst;
-
- return ret;
-}
-
-/// From os_unix.cpp
-OS::Time OS_Switch::get_time(bool utc) const {
- time_t t = time(nullptr);
- struct tm lt;
- if (utc) {
- gmtime_r(&t, <);
- } else {
- localtime_r(&t, <);
- }
- Time ret;
- ret.hour = lt.tm_hour;
- ret.min = lt.tm_min;
- ret.sec = lt.tm_sec;
- get_time_zone_info();
- return ret;
+OS::Date OS_Switch::get_date(bool local) const {
+ return OS::Date();
}
-/// From os_unix.cpp
-OS::TimeZoneInfo OS_Switch::get_time_zone_info() const {
- time_t t = time(nullptr);
- struct tm lt;
- localtime_r(&t, <);
- char name[16];
- strftime(name, 16, "%Z", <);
- name[15] = 0;
- TimeZoneInfo ret;
- ret.name = name;
-
- char bias_buf[16];
- strftime(bias_buf, 16, "%z", <);
- int bias;
- bias_buf[15] = 0;
- sscanf(bias_buf, "%d", &bias);
-
- // convert from ISO 8601 (1 minute=1, 1 hour=100) to minutes
- int hour = (int)bias / 100;
- int minutes = bias % 100;
- if (bias < 0) {
- ret.bias = hour * 60 - minutes;
- } else {
- ret.bias = hour * 60 + minutes;
- }
+OS::Time OS_Switch::get_time(bool local) const {
+ return OS::Time();
+}
- return ret;
+OS::TimeZoneInfo OS_Switch::get_time_zone_info() const {
+ return OS::TimeZoneInfo();
}
void OS_Switch::delay_usec(uint32_t p_usec) const {
@@ -392,6 +329,46 @@ bool OS_Switch::can_draw() const {
void OS_Switch::set_cursor_shape(CursorShape p_shape) {}
void OS_Switch::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {}
+bool g_swkbd_open = false;
+int g_eat_string_events = 0;
+u32 last_len = 0;
+s32 last_cursor = 0;
+
+void keyboard_string_changed_callback(const char *str, SwkbdChangedStringArg *arg) {
+ // We get a string changed event on appear, and another one on setting text.
+ if (g_eat_string_events) {
+ last_len = arg->stringLen;
+ g_eat_string_events--;
+ return;
+ }
+
+ if (arg->stringLen < last_len) {
+ OS_Switch::get_singleton()->key(KEY_BACKSPACE, true);
+ } else if (arg->stringLen != 0) {
+ OS_Switch::get_singleton()->key(str[arg->stringLen - 1], true);
+ }
+ last_len = arg->stringLen;
+}
+
+void keyboard_moved_cursor_callback(const char *str, SwkbdMovedCursorArg *arg) {
+ if (arg->cursorPos < last_cursor) {
+ OS_Switch::get_singleton()->key(KEY_LEFT, true);
+ } else {
+ OS_Switch::get_singleton()->key(KEY_RIGHT, true);
+ }
+
+ last_cursor = arg->cursorPos;
+}
+
+void keyboard_decided_enter_callback(const char *str, SwkbdDecidedEnterArg *arg) {
+ OS_Switch::get_singleton()->key(KEY_ENTER, true);
+ g_swkbd_open = false;
+}
+
+void keyboard_decided_cancel_callback() {
+ g_swkbd_open = false;
+}
+
void OS_Switch::key(uint32_t p_key, bool p_pressed) {
Ref ev;
ev.instance();
@@ -404,13 +381,17 @@ void OS_Switch::key(uint32_t p_key, bool p_pressed) {
void OS_Switch::run() {
if (!main_loop) {
- TRACE("No main loop?\n");
+ TRACE("no main loop???\n");
return;
}
main_loop->init();
- NintendoSwitch::get_singleton()->initialize_software_keyboard();
+ swkbdInlineLaunchForLibraryApplet(&inline_keyboard, SwkbdInlineMode_AppletDisplay, 0);
+ swkbdInlineSetChangedStringCallback(&inline_keyboard, keyboard_string_changed_callback);
+ swkbdInlineSetMovedCursorCallback(&inline_keyboard, keyboard_moved_cursor_callback);
+ swkbdInlineSetDecidedEnterCallback(&inline_keyboard, keyboard_decided_enter_callback);
+ swkbdInlineSetDecidedCancelCallback(&inline_keyboard, keyboard_decided_cancel_callback);
int last_touch_count = 0;
// maximum of 16 touches
@@ -420,7 +401,7 @@ void OS_Switch::run() {
hidInitializeTouchScreen();
while (appletMainLoop()) {
- if (NintendoSwitch::get_singleton()->is_virtual_keyboard_open()) {
+ if (g_swkbd_open) {
for (int i = 0; i < last_touch_count; i++) {
Ref st;
st.instance();
@@ -473,17 +454,18 @@ void OS_Switch::run() {
last_touch_count = touch_state.count;
}
-
- joypad->process();
- input->flush_buffered_events();
}
- NintendoSwitch::get_singleton()->update();
+ joypad->process();
+ input->flush_buffered_events();
+
+ swkbdInlineUpdate(&inline_keyboard, NULL);
if (Main::iteration())
break;
}
+ swkbdInlineClose(&inline_keyboard);
main_loop->finish();
}
@@ -496,54 +478,44 @@ bool OS_Switch::has_virtual_keyboard() const {
}
int OS_Switch::get_virtual_keyboard_height() const {
- if (!NintendoSwitch::get_singleton()->is_virtual_keyboard_open()) {
+ // todo: actually figure this out
+ if (!g_swkbd_open) {
return 0;
}
- return 400;
+ return 300;
}
-void OS_Switch::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
- NintendoSwitch::get_singleton()->show_virtual_keyboard(p_existing_text, NintendoSwitch::NORMAL_KEYBOARD);
-}
+void OS_Switch::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
+ if (!g_swkbd_open) {
+ g_swkbd_open = true;
-void OS_Switch::hide_virtual_keyboard() {
- NintendoSwitch::get_singleton()->hide_virtual_keyboard();
-}
+ SwkbdAppearArg appear_arg;
+ swkbdInlineMakeAppearArg(&appear_arg, SwkbdType_Normal);
+ swkbdInlineSetInputText(&inline_keyboard, p_existing_text.utf8().get_data());
+ swkbdInlineSetCursorPos(&inline_keyboard, p_existing_text.size() - 1);
-OS::PowerState OS_Switch::get_power_state() {
- if (!OS_Switch::psm_initialized) {
- return OS::POWERSTATE_UNKNOWN;
- }
-
- bool enough_power;
- psmIsEnoughPowerSupplied(&enough_power);
+ g_eat_string_events = 2;
- if (!enough_power) {
- return OS::PowerState::POWERSTATE_ON_BATTERY;
+ swkbdInlineAppear(&inline_keyboard, &appear_arg);
}
+}
- int percentage = OS_Switch::get_power_percent_left();
-
- if (percentage == 100) {
- return OS::PowerState::POWERSTATE_CHARGED;
- }
+void OS_Switch::hide_virtual_keyboard() {
+ printf("Hiding kbd!\n");
+ g_swkbd_open = false;
+ swkbdInlineDisappear(&inline_keyboard);
+}
- return OS::PowerState::POWERSTATE_CHARGING;
+OS::PowerState OS_Switch::get_power_state() {
+ return power_manager->get_power_state();
}
int OS_Switch::get_power_seconds_left() {
- WARN_PRINT("power_seconds_left is not implemented on this platform, defaulting to -1");
- return -1;
+ return power_manager->get_power_seconds_left();
}
int OS_Switch::get_power_percent_left() {
- if (!OS_Switch::psm_initialized) {
- return -1;
- }
-
- u32 voltage_percentage;
- psmGetBatteryChargePercentage(&voltage_percentage);
- return (int)voltage_percentage;
+ return power_manager->get_power_percent_left();
}
String OS_Switch::get_executable_path() const {
@@ -584,7 +556,9 @@ OS_Switch::OS_Switch() {
main_loop = nullptr;
visual_server = nullptr;
input = nullptr;
+ power_manager = nullptr;
gl_context = nullptr;
+ AudioDriverManager::add_driver(&driver_switch);
- AudioDriverManager::add_driver(&driver_audren);
+ swkbdInlineCreate(&inline_keyboard);
}
diff --git a/platform/switch/os_switch.h b/platform/switch/os_switch.h
index 4907b9f70d53..dc14c0cd1029 100644
--- a/platform/switch/os_switch.h
+++ b/platform/switch/os_switch.h
@@ -28,32 +28,29 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#include "api/switch_singleton.h"
+#include "audio_driver_switch.h"
#include "context_gl_switch_egl.h"
#include "core/os/input.h"
#include "core/os/os.h"
-#include "drivers/audren/audio_driver_audren.h"
#include "joypad_switch.h"
#include "main/input_default.h"
+#include "power_switch.h"
#include "servers/visual/visual_server_raster.h"
-#include
-
class OS_Switch : public OS {
int video_driver_index;
MainLoop *main_loop;
VideoMode current_videomode;
VisualServer *visual_server;
InputDefault *input;
+ PowerSwitch *power_manager;
ContextGLSwitchEGL *gl_context;
JoypadSwitch *joypad;
- AudioDriverAudren driver_audren;
+ AudioDriverSwitch driver_switch;
String switch_execpath;
SwkbdInline inline_keyboard;
- bool psm_initialized = false;
-
protected:
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -95,8 +92,8 @@ class OS_Switch : public OS {
virtual bool set_environment(const String &p_var, const String &p_value) const;
virtual String get_name() const;
virtual MainLoop *get_main_loop() const;
- virtual Date get_date(bool utc = false) const;
- virtual Time get_time(bool utc = false) const;
+ virtual Date get_date(bool local = false) const;
+ virtual Time get_time(bool local = false) const;
virtual TimeZoneInfo get_time_zone_info() const;
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
@@ -111,7 +108,7 @@ class OS_Switch : public OS {
virtual bool has_touchscreen_ui_hint() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
virtual void hide_virtual_keyboard();
virtual int get_virtual_keyboard_height() const;
diff --git a/platform/vita/export/export.h b/platform/vita/export/export.h
index 0e64de355cdb..86d1be7eda65 100644
--- a/platform/vita/export/export.h
+++ b/platform/vita/export/export.h
@@ -31,8 +31,6 @@
#ifndef VITA_EXPORT_H
#define VITA_EXPORT_H
-#ifndef MODULE_MONO_ENABLED
-
#include "core/io/file_access_memory.h"
#include "editor/editor_export.h"
#include "editor/editor_node.h"
@@ -51,6 +49,4 @@ typedef struct ParamSFOStruct {
int mksfoex(ParamSFOStruct *sfo, String outDir);
void register_vita_exporter();
-#endif // !MODULE_MONO_ENABLED
-
-#endif // !VITA_EXPORT_H
+#endif // VITA_EXPORT_H
diff --git a/scons b/scons
new file mode 100644
index 000000000000..e69de29bb2d1