We use a modified version of cengiz-pz's godot android share plugin[0],
which allows us to not only share text/images, but also sund files (see
PR here[1]). With this, the "Write WAV" button (bad naming, I know) will
allow the user to share a wav file of the morsed data to another app,
e.g. for sending some morse via Signal. It looks like Telegram doesn't
like wav files in general, so another audio format, might be interesting
(though it's hard to choose, as we don't have a proper encoder on board,
mp3 is a pain and opus or ogg is not compatible with very old Iphones).
Using the share plugin requires us to enable gradle build. An explicitly
set unique name is required as well, else sharing will fail (see [2]).
I'm not sure if the Share node needs to be an extra node or if we could
also use it as an autoload script instead, but I went with the way the
docs described it for now.
[0] https://github.com/cengiz-pz/godot-android-share-plugin/
[1] https://github.com/cengiz-pz/godot-android-share-plugin/pull/8
[2] https://github.com/cengiz-pz/godot-android-share-plugin/issues/7
* requires gradle build
* requires app name
To make things more accessible on mobile (nobody wants to try to "aim"
for the buttons") and also not waste screen space on other platforms we
stretch all widgets to match the window size.
The "Write Wav" button now lets the user download the resulting wav file
on web. Sadly, we cannot directly get a PackedByteArray from
AudioStreamWAV - the WAV header is only written as part of its
save_to_wav() method, which only accepts a string to a file and does all
the file handling itself. Therefore we now write the file to (temp)
disk, re-read it and then send it to the user. The other options I
currently see are a) to write the WAV header myself b) find a better way
to write a tempfile (at least tempfile naming seems to be a Godot >4.3
feature) or c) to contribute a get_wav_header() method AudioStreamWAV
upstream.
The "standardized" mimetype for wav seems to be audio/vnd.wave and not
audio/wav - I never knew! Many seem to point to RFC2361 regarding to
this.
Originally it was easier for the MorseBanner to have the states with
newest in front, but this makes the code harder to read and complicates
things in other places.
At some point it also might make sense to not use a range() in
MorseBanner, but use a int var + counter instead, as we often might only
consume a small number of elements. But as this is game programming,
"winging it" and getting something done seems to be the modus operandi.
Before this every instance of the MorseBanner had its own state, but as
we want to use the state also for other purposes, it doesn't make sense
to keep it in each instance. Therefore we now have an autoload that
keeps the state as a singleton. The MorseBanner now gets its state from
the autoload, so no more communication is needed between the main part
and the MorseBanner.