diff --git a/firefly/bindings.go b/firefly/bindings.go index 6a9f80d..50b945b 100644 --- a/firefly/bindings.go +++ b/firefly/bindings.go @@ -132,6 +132,9 @@ func getRandom() uint32 //go:wasmimport misc get_name func getName(index uint32, ptr unsafe.Pointer) uint32 +//go:wasmimport misc get_settings +func getSettings(index uint32) uint64 + //go:wasmimport misc restart func restart() diff --git a/firefly/misc.go b/firefly/misc.go index 6fae407..8ba9952 100644 --- a/firefly/misc.go +++ b/firefly/misc.go @@ -2,6 +2,153 @@ package firefly import "unsafe" +type Language uint16 + +const ( + English Language = 0x656e // en ๐Ÿ‡ฌ๐Ÿ‡ง ๐Ÿ’‚ + Dutch Language = 0x6e6c // nl ๐Ÿ‡ณ๐Ÿ‡ฑ ๐Ÿง€ + French Language = 0x6672 // fr ๐Ÿ‡ซ๐Ÿ‡ท ๐Ÿฅ + German Language = 0x6465 // de ๐Ÿ‡ฉ๐Ÿ‡ช ๐Ÿฅจ + Italian Language = 0x6974 // it ๐Ÿ‡ฎ๐Ÿ‡น ๐Ÿ• + Polish Language = 0x706c // pl ๐Ÿ‡ต๐Ÿ‡ฑ ๐ŸฅŸ + Romanian Language = 0x726f // ro ๐Ÿ‡ท๐Ÿ‡ด ๐Ÿง› + Russian Language = 0x7275 // ru ๐Ÿ‡ท๐Ÿ‡บ ๐Ÿช† + Spanish Language = 0x7370 // sp ๐Ÿ‡ช๐Ÿ‡ธ ๐Ÿ‚ + Swedish Language = 0x7365 // se ๐Ÿ‡ธ๐Ÿ‡ช โ„๏ธ + Turkish Language = 0x746b // tk ๐Ÿ‡น๐Ÿ‡ท ๐Ÿ•Œ + Ukrainian Language = 0x756b // uk ๐Ÿ‡บ๐Ÿ‡ฆ โœŠ + TokiPona Language = 0x7470 // tp ๐Ÿ‡จ๐Ÿ‡ฆ ๐Ÿ™‚ +) + +func (lang Language) Code() string { + b := [2]uint8{uint8(lang >> 8), uint8(lang)} + return unsafe.String(&b[0], 2) +} + +func (lang Language) NameEnglish() string { + switch lang { + case English: + return "English" + case Dutch: + return "Dutch" + case French: + return "French" + case German: + return "German" + case Italian: + return "Italian" + case Polish: + return "Polish" + case Romanian: + return "Romanian" + case Russian: + return "Russian" + case Spanish: + return "Spanish" + case Swedish: + return "Swedish" + case TokiPona: + return "TokiPona" + case Turkish: + return "Turkish" + case Ukrainian: + return "Ukrainian" + } + return lang.Code() +} + +func (lang Language) NameNative() string { + switch lang { + case English: + return "English" + case Dutch: + return "Nederlands" + case French: + return "Franรงais" + case German: + return "Deutsch" + case Italian: + return "Italiano" + case Polish: + return "Polski" + case Romanian: + return "Romรขnฤƒ" + case Russian: + return "ะ ัƒััะบะธะน" + case Spanish: + return "Espaรฑol" + case Swedish: + return "Svenska" + case TokiPona: + return "toki pona" + case Turkish: + return "Tรผrkรงe" + case Ukrainian: + return "ะฃะบั€ะฐั—ะฝััŒะบะฐ" + } + return lang.Code() +} + +func (lang Language) Encoding() string { + switch lang { + case English, Dutch, TokiPona: + return "ascii" + case Italian, Spanish, Swedish: + return "iso_8859_1" + case German, French: + return "iso_8859_2" + case Russian, Ukrainian: + return "iso_8859_5" + case Turkish: + return "iso_8859_9" + case Polish: + return "iso_8859_13" + case Romanian: + return "iso_8859_16" + } + return "ascii" +} + +type Theme struct { + ID uint8 + // The main color of text and boxes. + Primary Color + // The color of disable options, muted text, etc. + Secondary Color + // The color of important elements, active options, etc. + Accent Color + // The background color, the most contrast color to primary. + BG Color +} + +type Settings struct { + // The preferred color scheme of the player. + Theme Theme + + // The configured interface language. + Language Language + + // If true, the screen is rotated 180 degrees. + // + // In other words, the player holds the device upside-down. + // The touchpad is now on the right and the buttons are on the left. + RotateScreen bool + + // The player has photosensitivity. The app should avoid any rapid flashes. + ReduceFlashing bool + + // The player wants increased contrast for colors. + // + // If set, the black and white colors in the default + // palette are adjusted automatically. All other colors + // in the default palette or all colors in a custom palette + // should be adjusted by the app. + Contrast bool + + // If true, the player wants to see easter eggs, holiday effects, and weird jokes. + EasterEggs bool +} + // Log a debug message. func LogDebug(t string) { ptr := unsafe.Pointer(unsafe.StringData(t)) @@ -58,6 +205,34 @@ func GetName(p Peer) string { return unsafe.String(&buf[0], length) } +func GetSettings(p Peer) Settings { + raw := getSettings(uint32(p)) + code := uint16(raw>>8) | uint16(raw) + language := Language(code) + flags := raw >> 16 + themeRaw := raw >> 32 + theme := Theme{ + ID: uint8(themeRaw), + Primary: parseColor(themeRaw >> 20), + Secondary: parseColor(themeRaw >> 16), + Accent: parseColor(themeRaw >> 12), + BG: parseColor(themeRaw >> 8), + } + return Settings{ + Theme: theme, + Language: language, + RotateScreen: (flags & 0b0001) != 0, + ReduceFlashing: (flags & 0b0010) != 0, + Contrast: (flags & 0b0100) != 0, + EasterEggs: (flags & 0b1000) != 0, + } +} + +//go:inline +func parseColor(c uint64) Color { + return Color(c&0xf + 1) +} + // Exit the app after the current update is finished. func Quit() { quit() diff --git a/firefly/sudo/bindings.go b/firefly/sudo/bindings.go index a81f8f1..73e8d09 100644 --- a/firefly/sudo/bindings.go +++ b/firefly/sudo/bindings.go @@ -20,5 +20,11 @@ func runApp(authorPtr unsafe.Pointer, authorLen uint32, appPtr unsafe.Pointer, a //go:wasmimport sudo load_file func loadFile(pathPtr unsafe.Pointer, pathLen uint32, bufPtr unsafe.Pointer, bufLen uint32) uint32 +//go:wasmimport sudo remove_file +func removeFile(pathPtr unsafe.Pointer, pathLen uint32) + +//go:wasmimport sudo remove_dir +func removeDir(pathPtr unsafe.Pointer, pathLen uint32) + //go:wasmimport sudo get_file_size func getFileSize(pathPtr unsafe.Pointer, pathLen uint32) uint32 diff --git a/firefly/sudo/sudo.go b/firefly/sudo/sudo.go index 1ce8945..5733b9f 100644 --- a/firefly/sudo/sudo.go +++ b/firefly/sudo/sudo.go @@ -59,6 +59,17 @@ func RunApp(author string, app string) { ) } +// Check if the given file exists. +func FileExists(path string) bool { + return GetFileSize(path) != 0 +} + +func GetFileSize(path string) int { + pathPtr := unsafe.Pointer(unsafe.StringData(path)) + size := getFileSize(pathPtr, uint32(len(path))) + return int(size) +} + // Read a file from the FS. func LoadFile(path string) firefly.File { pathPtr := unsafe.Pointer(unsafe.StringData(path)) @@ -71,3 +82,13 @@ func LoadFile(path string) firefly.File { ) return firefly.File{Raw: raw} } + +func RemoveFile(path string) { + pathPtr := unsafe.Pointer(unsafe.StringData(path)) + removeFile(pathPtr, uint32(len(path))) +} + +func RemoveDir(path string) { + pathPtr := unsafe.Pointer(unsafe.StringData(path)) + removeDir(pathPtr, uint32(len(path))) +}