Made some fixes to touchscreen control detection:
* TouchScreenMode is activated on the first SDL2 FingerDown
* TouchScreenMode deactivates after the last finger is removed, and a
mouse event happens at least 5 ticks later.
* Touchscreen mode used to be detected based on SDL2 GetNumTouchDevices
but on a Macbook, the trackpad registers as a touch device - worse,
GetNumTouchDevices will only start returning 1 the first time some
devices are touched.
* The result was that on macOS the custom mouse cursor was drawn by
default, but on the first trackpad touch, would disappear in favor of
assuming the game is running on a touch screen device (which is not
the case).
* New method: the render engine has an IsFingerDown boolean which will
be true as long as at least one finger has registered a FingerDown
event, but not yet a FingerUp event.
* So as long as one finger is down, the mouse cursor can disappear and
then it comes back on release. This isn't perfectly ideal for pure
touch devices (ideally the cursor remains hidden until a mouse
movement without touch occurs).
* Update native.DefaultAuthor to get the name registered from the user's JWT
license in a way that avoids cyclic dependency errors.
* When plus_dpp.go#GetRegistration succeeds, it updates DefaultAuthor to the
registered name. The main.go now gets and prints the registered owner to
ensure this is populated on startup.
* Return correct ErrRegisteredFeature error when the FOSS version fails
to load embedded doodads.
* pkg/plus/dpp is the main plugin bridge, and defines nothing but an interface
that defines the Doodle++ surface area (referring to internal game types such
as doodad.Doodad or level.Level), but not their implementations.
* dpp.Driver (an interface) is the main API that other parts of the game will
call, for example "dpp.Driver.IsLevelSigned()"
* plus_dpp.go and plus_foss.go provide the dpp.Driver implementation for their
build; with plus_dpp.go generally forwarding function calls directly to the
proprietary dpp package and plus_foss.go generally returning false/errors.
* The bootstrap package simply assigns the above stub function to dpp.Driver
* pkg/plus/bootstrap is a package directly imported by main (in the doodle and
doodad programs) and it works around circular dependency issues: this package
simply assigns dpp.Driver to the DPP or FOSS version.
Miscellaneous fixes:
* File->Open in the editor and PlayScene will use the new Open Level window
instead of loading the legacy GotoLoadMenu scene.
* Deprecated legacy scenes: d.GotoLoadMenu() and d.GotoPlayMenu().
* The doodle-admin program depends on the private dpp package, so can not be
compiled in FOSS mode.
* Fix collision detection to allow actors to walk up slopes smoothly, without
losing any horizontal velocity.
* Fix scrolling a level canvas so that chunks near the right or bottom edge
of the viewpoint were getting culled prematurely.
* Centralize JavaScript exception catching logic to attach Go and JS stack
traces where possible to be more useful for debugging.
* Performance: flush all SDL2 textures from memory between scene transitions
in the app. Also add a `flush-textures` dev console command to flush the
textures at any time - they all should regenerate if still needed based on
underlying go.Images which can be garbage collected.
* Rework the Story Mode UI to display level thumbnails.
* Responsive UI: defaults to wide screen mode and shows 3 levels horizontally
but on narrow/mobile display, shows 2 levels per page in portrait.
* Add "Tiny" screenshot size (224x126) to fit the Story Mode UI.
* Make the pager buttons bigger and more touchable.
* Maximize the game window on startup unless the -w option with a specific
window resolution is provided.
* Fix display bug with rectangular doodads scrolling off screen.
* The default Author of new files will be your registration name, if available
before using your $USER name.
* Add an exception catcher that pops open a UI window showing errors that
occur in doodad scripts during gameplay.
* Shows a preview of the header of the error (character wrapped) with a
Copy button to copy the full raw text to clipboard for inspection.
* Buttons to dismiss the modal once or stop any further errors from
opening during this gameplay session (until next restart).
* Add developer shell commands to test the exception catcher:
- 'throw <message>' to throw a custom message.
- 'throw2' to stress test a "long" message.
- 'throw3' to throw a realistic message copied from an actual error.
* Scripting engine: console.log() and friends will now insert the script
VM's name in front of its messages (the filename + actor ID).
Added a new level property: Difficulty
* An enum ranging from -1, 0, 1 (Peaceful, Normal, Hard)
* Default difficulty is Normal; pre-existing levels are Normal by
default per the zero value.
Doodad scripts can read the difficulty via the new global variable
`Level.Difficulty` and some doodads have been updated:
* Azulians: on Peaceful they ignore all player characters, and on Hard
they are in "hunt mode": infinite aggro radius and they're aggressive
to all characters.
* Bird: on Peaceful they will not dive and attack any player character.
Other spit and polish:
* New Level/Level Properties UI reworked into a magicform.
* New "PromptPre(question, answer, func)" function for prompting the
user with the developer shell, but pre-filling in an answer for them
to either post or edit.
* magicform has a PromptUser field option for simple Text/Int fields
which present as buttons, so magicform can prompt and update the
variable itself.
* Don't show the _autosave.doodad in the Doodad Dropper window.
Two new tools added to the Level Editor:
* Pan Tool: left-click to scroll the level around safely.
* Text Tool: write text onto your level.
Features of the Text Tool:
* Can choose from the game's built-in fonts, size and enter the message
you want to write.
* The mouse cursor previews the text when hovered over the level.
* Click to "stamp" the text onto your level. The currently selected
color swatch will be used to color the text in.
* Adds two new fonts: Azulian.ttf and Rive.ttf that can be selected in
the Text Tool.
Some implementation notes:
* Added package native/engine_sdl.go that handles the lower-level
SDL2_TTF logic to rasterize the text into a black&white image.
* WASM not supported yet (if the game even still built for WASM);
native/engine_wasm.go stubs out the TextToImage() call with a "not
supported" error just in case.
Other changes:
* New Toolbar icons: they are 24x24 instead of 32x32 to make more room
for more tools.
* The toolbar now shows two buttons per row for a more densely packed
layout. For very narrow screen widths (< 600px) the default Vertical
Toolbar layout will use one-button-per-row to not eat too much screen
real estate.
* In the Horizontal Toolbars layout there are 2 buttons per column.
* File->Publish Level in the Level Editor opens the Publish window,
where you can embed custom doodads into your level and export a
portable .level file you can share with others.
* Currently does not actually export a level file yet.
* The dialog lists all unique doodad names in use in your level, and
designates which are built-ins and which are custom (paginated).
* A checkbox would let the user embed built-in doodads into their level,
as well, locking it in to those versions and not using updated
versions from future game releases.
UI Improvements:
* Added styling for a "Primary" UI button, rendered in deep blue.
* Pop-up modals (Alert, Confirm) color their Ok button as Primary.
* The Enter key pressed during an Alert or Confirm modal will invoke its
default button and close the modal, corresponding to its Primary
button.
* The developer console is now opened with the tilde/grave key ` instead
of the Enter key, so that the Enter key is free to click through
modals.
* In the "Open/Edit Drawing" window, a "Browse..." button is added to
the level and doodad sections, spawning a native File Open dialog to
pick a .level or .doodad outside the config root.
* You can now browse for a custom wallpaper image to use with your
levels. A platform-native file picker dialog is used (no WASM support)
* In the New/Edit Level Properties dialog, the Wallpaper drop-down
includes an option to browse for a custom map.
* When editing an existing level: the wallpaper takes effect immediately
in your level once the file is picked. For NEW levels, the wallpaper
will appear once the "Continue" button is pressed.
* All common image types supported: png, jpeg, gif.
* The wallpaper is embedded in the level using the filepath
"assets/wallpapers/custom.b64img" as a Base64-encoded blob of the
image data.
* The `doodad show` command will list the names and sizes of files
embedded in levels. `doodad show --attachment <name>` will get an
attachment and print it to the console window.
* To extract a wallpaper image from a level:
`doodad show -a assets/wallpapers/custom.b64img | base64 -d > out.png`