diff --git a/assets/weather-icons/svg/wi-cloudy.svg b/assets/weather-icons/svg/wi-cloudy.svg
new file mode 100644
index 00000000..c3eaf41d
--- /dev/null
+++ b/assets/weather-icons/svg/wi-cloudy.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-day-cloudy.svg b/assets/weather-icons/svg/wi-day-cloudy.svg
new file mode 100644
index 00000000..cf63543a
--- /dev/null
+++ b/assets/weather-icons/svg/wi-day-cloudy.svg
@@ -0,0 +1,26 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-day-sunny.svg b/assets/weather-icons/svg/wi-day-sunny.svg
new file mode 100644
index 00000000..eafcd77d
--- /dev/null
+++ b/assets/weather-icons/svg/wi-day-sunny.svg
@@ -0,0 +1,27 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-fog.svg b/assets/weather-icons/svg/wi-fog.svg
new file mode 100644
index 00000000..cf06f8f8
--- /dev/null
+++ b/assets/weather-icons/svg/wi-fog.svg
@@ -0,0 +1,18 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-night-alt-cloudy.svg b/assets/weather-icons/svg/wi-night-alt-cloudy.svg
new file mode 100644
index 00000000..fcd1496d
--- /dev/null
+++ b/assets/weather-icons/svg/wi-night-alt-cloudy.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-night-clear.svg b/assets/weather-icons/svg/wi-night-clear.svg
new file mode 100644
index 00000000..053b2de9
--- /dev/null
+++ b/assets/weather-icons/svg/wi-night-clear.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-rain.svg b/assets/weather-icons/svg/wi-rain.svg
new file mode 100644
index 00000000..7ecef3fe
--- /dev/null
+++ b/assets/weather-icons/svg/wi-rain.svg
@@ -0,0 +1,23 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-snow.svg b/assets/weather-icons/svg/wi-snow.svg
new file mode 100644
index 00000000..56afebf9
--- /dev/null
+++ b/assets/weather-icons/svg/wi-snow.svg
@@ -0,0 +1,27 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-sprinkle.svg b/assets/weather-icons/svg/wi-sprinkle.svg
new file mode 100644
index 00000000..c26b2075
--- /dev/null
+++ b/assets/weather-icons/svg/wi-sprinkle.svg
@@ -0,0 +1,20 @@
+
+
+
diff --git a/assets/weather-icons/svg/wi-thunderstorm.svg b/assets/weather-icons/svg/wi-thunderstorm.svg
new file mode 100644
index 00000000..52555ec7
--- /dev/null
+++ b/assets/weather-icons/svg/wi-thunderstorm.svg
@@ -0,0 +1,21 @@
+
+
+
diff --git a/lib/Weather/WeatherIcons48.h b/lib/Weather/WeatherIcons48.h
index b92bc221..d7e5f349 100644
--- a/lib/Weather/WeatherIcons48.h
+++ b/lib/Weather/WeatherIcons48.h
@@ -1,215 +1,196 @@
#pragma once
#include
-// Generated from erikflowers/weather-icons (font + css mappings)
-// 48x48, 1-bit, MSB-first, row-major, rotated for device orientation
+// Generated from erikflowers/weather-icons SVGs.
+// 48x48, 1-bit, MSB-first, row-major.
+// Regenerate with: python scripts/generate_weather_icons.py --fetch
static const uint8_t WI48_CLEAR_DAY[] = {
- 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFE, 0x7F, 0xF8, 0x7F, 0xFC, 0x7F,
- 0xFC, 0x3F, 0xFC, 0xFF, 0xF8, 0x3F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF0, 0x3F, 0xFE, 0x0F, 0xFF, 0xFF,
- 0xC0, 0x7F, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0x8F,
- 0xC0, 0x0F, 0xC3, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF,
- 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xC0, 0x7F, 0xFF, 0xFF, 0xF8, 0x3F, 0xF0,
- 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE0,
- 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFE, 0x1F, 0xFF, 0x00, 0xE1, 0xFF, 0xFE, 0x1F, 0x00,
- 0x00, 0xE1, 0xFF, 0xFE, 0x1F, 0x00, 0x00, 0xE1, 0xFF, 0xFE, 0x1F, 0x00, 0x81, 0xE1, 0xFF, 0xFE,
- 0x1F, 0x81, 0xFF, 0xE0, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xF0,
- 0x7F, 0xF8, 0x3F, 0xFF, 0xFF, 0xF0, 0x3F, 0xF0, 0x3F, 0xFF, 0xFF, 0xF8, 0x1F, 0xE0, 0x7F, 0xFF,
- 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03,
- 0xFF, 0xFF, 0xFF, 0xCF, 0xC0, 0x0F, 0xE7, 0xFF, 0xFF, 0x8F, 0xF0, 0x3F, 0xC3, 0xFF, 0xFF, 0x0F,
- 0xFF, 0xFF, 0xC0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFC, 0x1F, 0xFF, 0xFF, 0xE0, 0x3F,
- 0xFC, 0x1F, 0xFC, 0xFF, 0xF0, 0x3F, 0xFC, 0x3F, 0xF8, 0x7F, 0xFC, 0x3F, 0xFE, 0x7F, 0xF8, 0x7F,
- 0xFE, 0x7F, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFE, 0x1F, 0xFE, 0x7F, 0xF8, 0xFF,
+ 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC1, 0xFF,
+ 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xE7, 0xF8, 0x1F, 0xE7, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xF0, 0x7F, 0xFF,
+ 0xFF, 0xFC, 0x1F, 0xF8, 0x3F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xF8, 0x7F, 0xFE, 0x3F, 0xFF,
+ 0xFF, 0xF8, 0x7F, 0xFE, 0x1F, 0xFF, 0xC0, 0xF8, 0xFF, 0xFF, 0x1F, 0x03, 0x80, 0x78, 0xFF, 0xFF, 0x1E, 0x01,
+ 0x80, 0x78, 0xFF, 0xFF, 0x1E, 0x01, 0xC0, 0xF8, 0xFF, 0xFF, 0x1F, 0x03, 0xFF, 0xF8, 0x7F, 0xFE, 0x1F, 0xFF,
+ 0xFF, 0xF8, 0x7F, 0xFE, 0x1F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFC, 0x3F, 0xFF, 0xFF, 0xFC, 0x1F, 0xF8, 0x3F, 0xFF,
+ 0xFF, 0xFE, 0x0F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xE7, 0xF0, 0x0F, 0xE7, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xFF,
+ 0xFF, 0x83, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0x7F,
+ 0xFE, 0x1F, 0xFE, 0x7F, 0xF8, 0x7F, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_CLEAR_NIGHT[] = {
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
- 0xF0, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0xFE, 0x07, 0xFF,
- 0xFF, 0xFF, 0xE1, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
- 0xC1, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xC1, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xE0, 0xFF, 0xFF, 0x00,
- 0x0F, 0xFF, 0xE0, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xF0, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF0, 0xFF,
- 0xFE, 0x01, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF,
- 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x07,
- 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC1, 0xFF,
- 0xFF, 0x81, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xE0, 0x7F, 0xFE,
- 0x07, 0xFF, 0xFF, 0xE0, 0x1F, 0xF8, 0x0F, 0xFF, 0xFF, 0xF0, 0x03, 0x80, 0x1F, 0xFF, 0xFF, 0xFC,
- 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xC0, 0x03, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x07, 0xFF, 0xFF,
+ 0xFE, 0x01, 0xFF, 0x03, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0x83, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0x83, 0xFF, 0xFF,
+ 0xF8, 0x1F, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF,
+ 0xE0, 0x7F, 0xFF, 0xE0, 0x7F, 0xFF, 0xE0, 0x7F, 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF,
+ 0xC0, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xC0, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
+ 0xC1, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xC1, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0x81, 0xFF, 0xFF, 0xFF, 0xF8, 0x01,
+ 0x81, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1,
+ 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x83,
+ 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0x03, 0xE0, 0x7F, 0xFF, 0xFF, 0xFE, 0x07,
+ 0xE0, 0x3F, 0xFF, 0xFF, 0xFE, 0x07, 0xF0, 0x1F, 0xFF, 0xFF, 0xFC, 0x0F, 0xF0, 0x1F, 0xFF, 0xFF, 0xF8, 0x0F,
+ 0xF8, 0x0F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFC, 0x07, 0xFF, 0xFF, 0xE0, 0x1F, 0xFC, 0x01, 0xFF, 0xFF, 0xC0, 0x3F,
+ 0xFE, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF,
+ 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_PARTLY_CLOUDY_DAY[] = {
- 0xFE, 0x3F, 0xFC, 0x3F, 0xFE, 0x3F, 0xFE, 0x1F, 0xFE, 0x7F, 0xFC, 0x3F, 0xFE, 0x0F, 0xFF, 0xFF,
- 0xF8, 0x3F, 0xFE, 0x07, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0x83,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0xE3, 0xFF,
- 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x07, 0xE0,
- 0x00, 0x0F, 0xFF, 0xFC, 0x1F, 0xF0, 0x00, 0x07, 0xFF, 0xF8, 0x3F, 0xE0, 0x7F, 0x03, 0xFF, 0xF8,
- 0x7F, 0xC0, 0xFF, 0x81, 0xFF, 0xF0, 0x7F, 0xC1, 0xFF, 0xC1, 0xFF, 0xF0, 0x7F, 0x83, 0xFF, 0xE0,
- 0x00, 0x70, 0xFF, 0x83, 0xFF, 0xE0, 0x00, 0x70, 0xFF, 0x87, 0xFF, 0xF0, 0x00, 0x70, 0xFF, 0x87,
- 0xFF, 0xF0, 0x80, 0xF0, 0xFF, 0x87, 0xFF, 0xF0, 0xFF, 0xF0, 0x7C, 0x07, 0xFF, 0xF0, 0xFF, 0xF0,
- 0x78, 0x07, 0xFF, 0xF0, 0xFF, 0xF8, 0x30, 0x07, 0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xF0,
- 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x07, 0xFF,
- 0xFF, 0xF0, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE,
- 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0x9E, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0x0E, 0x1F, 0xFF, 0xFF, 0xF0,
- 0xFE, 0x0E, 0x1F, 0xFF, 0xFF, 0xF0, 0xFE, 0x1E, 0x1F, 0xFF, 0xFF, 0xF0, 0xFE, 0x1E, 0x1F, 0xFF,
- 0xFF, 0xF0, 0xFF, 0x3E, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,
- 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF0,
- 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xE0, 0x0F,
- 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xF0, 0xFF, 0xFF,
- 0xFE, 0x07, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xE0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xF3, 0xFF, 0x7F,
+ 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x9F, 0xFF, 0xF8, 0x7F,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF,
+ 0xFF, 0xF8, 0x00, 0x1C, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0x0F, 0xFF, 0xFF, 0xC1, 0xF0, 0x7F, 0x87, 0xFF,
+ 0xFF, 0x87, 0xFC, 0x3F, 0xC7, 0xFF, 0xFF, 0x8F, 0xFE, 0x3F, 0xE7, 0xFF, 0xFF, 0x1F, 0xFF, 0x1F, 0xE7, 0x83,
+ 0xFF, 0x1F, 0xFF, 0x1F, 0xE3, 0x81, 0xFE, 0x3F, 0xFF, 0x83, 0xE7, 0x83, 0xF8, 0x3F, 0xFF, 0x80, 0xE7, 0xFF,
+ 0xF0, 0x3F, 0xFF, 0x80, 0x07, 0xFF, 0xE1, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF,
+ 0x8F, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xCE, 0x7F, 0x8F, 0xFF, 0xFF, 0xFF, 0x8C, 0x3F,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0x8E, 0x3F, 0xC7, 0xFF, 0xFF, 0xFF, 0x1F, 0x7F, 0xE1, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF,
+ 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_PARTLY_CLOUDY_NIGHT[] = {
- 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x60,
- 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x08, 0x00, 0x01, 0xFF, 0xFF, 0xFC,
- 0x0C, 0x00, 0x00, 0xFF, 0xFC, 0x60, 0x1C, 0x0F, 0xE0, 0x7F, 0xF8, 0x00, 0x38, 0x1F, 0xF0, 0x3F,
- 0xF8, 0x00, 0x78, 0x3F, 0xF8, 0x3F, 0xF8, 0x01, 0xF0, 0x7F, 0xFC, 0x1F, 0xF8, 0x0F, 0xF0, 0x7F,
- 0xFC, 0x1F, 0xF8, 0x7F, 0xF0, 0xFF, 0xFE, 0x1F, 0xF8, 0x7F, 0xF0, 0xFF, 0xFE, 0x1F, 0xF8, 0x3F,
- 0xF0, 0xFF, 0xFE, 0x1F, 0xF8, 0x3F, 0x80, 0xFF, 0xFE, 0x1F, 0xFC, 0x1F, 0x00, 0xFF, 0xFE, 0x1F,
- 0xFC, 0x1E, 0x00, 0xFF, 0xFE, 0x1F, 0xFE, 0x04, 0x03, 0xFF, 0xFE, 0x1F, 0xFE, 0x00, 0x1F, 0xFF,
- 0xFE, 0x1F, 0xFF, 0x00, 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0x80, 0x7F, 0xFF, 0xFE, 0x1F, 0xFF, 0xE0,
- 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xE1, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x1F,
- 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC3, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC3, 0xFF, 0xFF,
- 0xFE, 0x1F, 0xFF, 0xC3, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC3, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC1,
- 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xE1, 0xFF, 0xFF, 0xFE, 0x1F,
- 0xFF, 0xE0, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0x3F, 0xFF,
- 0xFE, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFC, 0x01, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE,
- 0x00, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x00, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFE, 0x1F,
- 0xFF, 0xFF, 0xF0, 0x7F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x7F, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F,
- 0xF8, 0x3F, 0xFF, 0xFF, 0xF8, 0x1F, 0xF0, 0x3F, 0xFF, 0xFF, 0xFC, 0x07, 0xC0, 0x7F, 0xFF, 0xFF,
- 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF8, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xF8, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x03, 0xF8, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xF8, 0xFF, 0xFF, 0xF0, 0x3F, 0x03, 0xF8, 0x7F,
+ 0xFF, 0xF0, 0xFF, 0xC1, 0xFC, 0x3F, 0xFF, 0xE1, 0xFF, 0xF0, 0xFC, 0x1F, 0xFF, 0xC3, 0xFF, 0xF8, 0x7E, 0x07,
+ 0xFF, 0xC3, 0xFF, 0xF8, 0x7F, 0x01, 0xFF, 0xC7, 0xFF, 0xFC, 0x7F, 0x83, 0xFF, 0x87, 0xFF, 0xFC, 0x07, 0xC3,
+ 0xFE, 0x0F, 0xFF, 0xFC, 0x01, 0xC3, 0xF8, 0x0F, 0xFF, 0xFC, 0x00, 0x07, 0xF0, 0x0F, 0xFF, 0xFE, 0x80, 0x07,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
+ 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F,
+ 0xE0, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xF0, 0x1F, 0xFF, 0xFF, 0xE0, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F,
+ 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_OVERCAST[] = {
- 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xC1, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFE,
- 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xFF,
- 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xF0, 0x7F, 0xFF, 0xFF, 0xC0, 0x3F, 0x80,
- 0x0F, 0xFF, 0xFF, 0x80, 0x7F, 0x00, 0x07, 0xFF, 0xFF, 0x87, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0x0F,
- 0xFC, 0x1F, 0x81, 0xFF, 0xFF, 0x1F, 0xFC, 0x3F, 0xE1, 0xFF, 0xFE, 0x1F, 0xF8, 0x7F, 0xF0, 0xFF,
- 0xFE, 0x3F, 0xF8, 0x7F, 0xF0, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xF8, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF,
- 0xF8, 0xFF, 0xFE, 0x3F, 0xF8, 0xFF, 0xF8, 0xFF, 0xFE, 0x1F, 0xC0, 0xFF, 0xF8, 0xFF, 0xFE, 0x1F,
- 0x80, 0xFF, 0xF8, 0xFF, 0xFF, 0x0E, 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0x06, 0x0F, 0xFF, 0xF8, 0xFF,
- 0xFF, 0x8C, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0x88, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF,
- 0xF8, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF1,
- 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xF8, 0xFF,
- 0xFF, 0xF1, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF,
- 0xF8, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xFC,
- 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xF8, 0xFF,
- 0xFF, 0xFF, 0x80, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F,
- 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xE1, 0xFF, 0xFF, 0xFF,
- 0xFC, 0x1F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x1F, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xC7, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xE3, 0xFF,
+ 0xFF, 0xF0, 0x00, 0xFF, 0xE3, 0xFF, 0xFF, 0xE0, 0x60, 0x7F, 0xF0, 0xFF, 0xFF, 0xC3, 0xFC, 0x3F, 0xF0, 0x1F,
+ 0xFF, 0x87, 0xFE, 0x1F, 0xF0, 0x0F, 0xFF, 0x8F, 0xFF, 0x0F, 0xFF, 0x87, 0xFF, 0x1F, 0xFF, 0x8F, 0xFF, 0xE3,
+ 0xFF, 0x1F, 0xFF, 0x8F, 0xFF, 0xE3, 0xFC, 0x1F, 0xFF, 0xC0, 0x7F, 0xF1, 0xF8, 0x3F, 0xFF, 0xC0, 0x3F, 0xF1,
+ 0xE0, 0x7F, 0xFF, 0xFC, 0x1F, 0xF1, 0xE3, 0xFF, 0xFF, 0xFF, 0x0F, 0xF1, 0xC7, 0xFF, 0xFF, 0xFF, 0xC7, 0xE3,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0xC7, 0xE3, 0x8F, 0xFF, 0xFF, 0xFF, 0xE3, 0x87, 0x8F, 0xFF, 0xFF, 0xFF, 0xE2, 0x0F,
+ 0x8F, 0xFF, 0xFF, 0xFF, 0xE2, 0x1F, 0x8F, 0xFF, 0xFF, 0xFF, 0xE3, 0x7F, 0x8F, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF,
+ 0xC7, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF,
+ 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_FOG[] = {
- 0xFF, 0xFF, 0xFD, 0xE7, 0xFF, 0x0F, 0xFF, 0xFF, 0xE1, 0xC3, 0xFF, 0x0F, 0xFF, 0xFF, 0xC1, 0xC3,
- 0xFF, 0x0F, 0xFF, 0xFF, 0x81, 0xC3, 0xFF, 0x0F, 0xFF, 0xFF, 0x01, 0xC3, 0xFF, 0x0F, 0xFF, 0xFE,
- 0x07, 0xC3, 0xFF, 0x0F, 0xFF, 0xFE, 0x0F, 0xC3, 0xCF, 0x0F, 0xFF, 0xFC, 0x1F, 0xC3, 0x87, 0x0F,
- 0xFF, 0xFC, 0x1F, 0xC3, 0x87, 0x0F, 0xFF, 0xFC, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xFC, 0x3F, 0xC3,
- 0x87, 0x0F, 0xFF, 0xFC, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xF0, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xC0,
- 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0x80, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0x00, 0x3F, 0xC3, 0x87, 0x0F,
- 0xFE, 0x07, 0xFF, 0xC3, 0x87, 0x0F, 0xFC, 0x0F, 0xFF, 0xC3, 0x87, 0x0F, 0xFC, 0x1F, 0xFF, 0xC3,
- 0x87, 0x0F, 0xF8, 0x3F, 0xFF, 0xC3, 0x87, 0x0F, 0xF8, 0x7F, 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0x7F,
- 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0x7F, 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0xFF, 0xFF, 0xC3, 0x87, 0x0F,
- 0xF0, 0xFF, 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0xFF, 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0xFF, 0xFF, 0xC3,
- 0x87, 0x0F, 0xF0, 0xFF, 0xFF, 0xC3, 0x87, 0x0F, 0xF0, 0x7F, 0xFF, 0xC3, 0x87, 0x0F, 0xF8, 0x7F,
- 0xFF, 0xC3, 0x87, 0x0F, 0xF8, 0x3F, 0xFF, 0xC3, 0x87, 0x0F, 0xF8, 0x3F, 0xFF, 0xC3, 0x87, 0x0F,
- 0xFC, 0x1F, 0xFF, 0xC3, 0x87, 0x0F, 0xFE, 0x07, 0xFF, 0xC3, 0x87, 0x0F, 0xFE, 0x00, 0xFF, 0xC3,
- 0x87, 0x0F, 0xFF, 0x00, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xC0, 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xE0,
- 0x3F, 0xC3, 0x87, 0x0F, 0xFF, 0xFC, 0x1F, 0xC3, 0x87, 0x0F, 0xFF, 0xFC, 0x1F, 0xC3, 0x87, 0x0F,
- 0xFF, 0xFE, 0x0F, 0xC3, 0x87, 0x0F, 0xFF, 0xFE, 0x07, 0xC3, 0x87, 0x0F, 0xFF, 0xFF, 0x03, 0xC3,
- 0x87, 0x1F, 0xFF, 0xFF, 0x81, 0xC3, 0x87, 0xFF, 0xFF, 0xFF, 0xC1, 0xC3, 0x87, 0xFF, 0xFF, 0xFF,
- 0xE1, 0xC3, 0x87, 0xFF, 0xFF, 0xFF, 0xF9, 0xC7, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xC1, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xF8, 0x7F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFC, 0x7F, 0xFF,
+ 0xFF, 0xF8, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFE, 0x01, 0xFF,
+ 0xFF, 0x80, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFC, 0x3F,
+ 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x1F, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F,
+ 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF,
+ 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01,
+ 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_DRIZZLE[] = {
- 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
- 0x03, 0xF8, 0x1F, 0xFF, 0xFF, 0xFE, 0x07, 0xFC, 0x0F, 0xFF, 0xFF, 0xFE, 0x0F, 0xFE, 0x0F, 0xFF,
- 0xFF, 0xFC, 0x1F, 0xFF, 0x07, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0x07, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF,
- 0x87, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
- 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
- 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF,
- 0x00, 0x7F, 0xF8, 0x3F, 0xFF, 0xFE, 0x00, 0x3F, 0xF8, 0x3F, 0xE1, 0xFC, 0x00, 0x3F, 0xF0, 0x7F,
- 0xC0, 0xF8, 0x00, 0x3F, 0xF0, 0x7F, 0xC0, 0xF0, 0x00, 0x3F, 0xF0, 0xFF, 0xE1, 0xF8, 0x00, 0x3F,
- 0xF0, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xF0, 0xFF, 0xFF, 0xFF,
- 0x80, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xF0, 0x7F, 0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0x7F,
- 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x7F, 0xFC, 0x01, 0xFF, 0xFF, 0xF8, 0x3F, 0xFC, 0x01, 0xFF, 0xFF,
- 0xF8, 0x1F, 0xFE, 0x03, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0x83, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xEF,
- 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0x87, 0xFF, 0xFF, 0xC0,
- 0x3F, 0xFF, 0x87, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0x87, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0x07, 0xFF,
- 0xFF, 0xFC, 0x1F, 0xFF, 0x0F, 0xFF, 0xFF, 0xFE, 0x0F, 0xFE, 0x0F, 0xFF, 0xFF, 0xFE, 0x07, 0xFC,
- 0x1F, 0xFF, 0xFF, 0xFF, 0x01, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
- 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF,
+ 0xFF, 0xC7, 0xFF, 0xFF, 0x03, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xFC, 0x07, 0xFF, 0xFF, 0x00, 0x3F,
+ 0xF0, 0x07, 0xFF, 0xFF, 0x00, 0x0F, 0xF0, 0x7F, 0xFF, 0x9F, 0xFE, 0x0F, 0xE1, 0xFF, 0xFF, 0x8F, 0xFF, 0x87,
+ 0xC3, 0xFF, 0xFF, 0x0F, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0x0F, 0xFF, 0xC3, 0xC7, 0xFF, 0xBF, 0x9F, 0xFF, 0xE3,
+ 0x87, 0xFF, 0x1F, 0xFF, 0xFF, 0xE1, 0x87, 0xFE, 0x1F, 0xFF, 0xFF, 0xE1, 0x87, 0xFE, 0x0F, 0xFF, 0xFF, 0xE1,
+ 0x87, 0xFC, 0x0F, 0xFF, 0xFF, 0xE1, 0xC7, 0xFC, 0x0F, 0xFF, 0xFF, 0xE3, 0xC3, 0xFE, 0x0F, 0x9F, 0xFF, 0xC3,
+ 0xC3, 0xFF, 0x1F, 0x0F, 0xFF, 0xC3, 0xE1, 0xFF, 0xFE, 0x07, 0xFF, 0x87, 0xF0, 0x7F, 0xFE, 0x07, 0xFE, 0x0F,
+ 0xF0, 0x0F, 0xFC, 0x03, 0xF0, 0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0xF0, 0x3F, 0xFE, 0x0F, 0xF8, 0x01, 0xF0, 0x7F,
+ 0xFF, 0xCF, 0xF8, 0x01, 0xF3, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_RAIN[] = {
- 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07,
- 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8,
- 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xE0, 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF,
- 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFC,
- 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
- 0xFE, 0x07, 0xFF, 0xFF, 0xFE, 0x01, 0xFE, 0x00, 0xFF, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x0F, 0xFF,
- 0xF0, 0x0F, 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x3F, 0xFF, 0xE0, 0x00, 0xFF, 0xE0, 0xFF, 0xFF, 0xFE,
- 0x00, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF,
- 0xFE, 0x03, 0xFF, 0xFF, 0x83, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0x87, 0xFF, 0xFE, 0x00, 0x07, 0xFF,
- 0x87, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0x87, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0x87, 0xFF, 0xFF, 0xFF,
- 0x00, 0x01, 0x87, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0x83, 0xFF, 0xFE, 0x1F, 0xFE, 0x01, 0x83, 0xFF,
- 0xFE, 0x01, 0xFF, 0xE3, 0xC3, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x03, 0xFF,
- 0xC0, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF,
- 0x80, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xF1, 0xFF, 0xFC, 0x01, 0xFF, 0xFC, 0x3F, 0xFF, 0xFE, 0x01,
- 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x81, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF,
- 0xFF, 0xE0, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x3F, 0xE0,
- 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE,
- 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF,
+ 0xFF, 0x87, 0xFF, 0xFF, 0x03, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xFC, 0x07, 0xFF, 0xFF, 0x00, 0x3F,
+ 0xF0, 0x07, 0xFF, 0xFF, 0x00, 0x0F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87,
+ 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3,
+ 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x87, 0xFF, 0xDF, 0x9F, 0x3F, 0xE1,
+ 0x87, 0xFF, 0x8F, 0x1F, 0x1F, 0xE1, 0xC7, 0xFF, 0x8F, 0x0E, 0x1F, 0xE3, 0xC3, 0xFF, 0x0F, 0x1E, 0x1F, 0xC3,
+ 0xC1, 0xFF, 0x0E, 0x1E, 0x3F, 0x83, 0xE0, 0xFF, 0x1E, 0x1C, 0x3F, 0x87, 0xF0, 0x7E, 0x1E, 0x3C, 0x3E, 0x0F,
+ 0xF8, 0x0E, 0x1E, 0x3C, 0x70, 0x1F, 0xFC, 0x0E, 0x3C, 0x3C, 0x70, 0x3F, 0xFE, 0x0E, 0x3C, 0x38, 0x70, 0x7F,
+ 0xFF, 0xEC, 0x3C, 0x78, 0x7F, 0xFF, 0xFF, 0xFC, 0x38, 0x78, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x70, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x78, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0xF1, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xF1, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_SNOW[] = {
- 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07,
- 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8,
- 0x1F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xE0, 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF,
- 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFC,
- 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFC, 0x3C, 0x3F,
- 0xF0, 0x0F, 0xFF, 0xFC, 0x3C, 0x3F, 0xF0, 0x3F, 0xFF, 0xFC, 0x3C, 0x3F, 0xE0, 0xFF, 0xFF, 0xFE,
- 0x7E, 0x7F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE7, 0xE7, 0xF3, 0x87, 0xFF, 0xFF, 0xC3, 0xC3, 0xE1,
- 0x87, 0xFF, 0xFF, 0xC3, 0xC3, 0xE1, 0x87, 0xFF, 0xFF, 0xC3, 0xC3, 0xE1, 0x87, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFC, 0x3C, 0x3F, 0xC1, 0xFF, 0xFF, 0xFC, 0x3C, 0x3F,
- 0xC0, 0xFF, 0xFF, 0xFC, 0x3C, 0x3F, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFC, 0x3F, 0xFF, 0xFE, 0x01,
- 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x81, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF,
- 0xFF, 0xE0, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x3F, 0xE0,
- 0x7F, 0xFF, 0xFF, 0xF8, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE,
- 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF,
+ 0xFF, 0xF8, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x7F, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF,
+ 0xFF, 0x87, 0xFF, 0xFF, 0x03, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xFC, 0x07, 0xFF, 0xFF, 0x00, 0x3F,
+ 0xF0, 0x07, 0xFF, 0xFF, 0x00, 0x1F, 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x0F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87,
+ 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3,
+ 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1,
+ 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
+ 0xC3, 0xFF, 0xFE, 0x3F, 0xFF, 0x83, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x07, 0xF0, 0x7F, 0xFE, 0x7F, 0xFE, 0x0F,
+ 0xF0, 0x0F, 0x3F, 0xFC, 0xF0, 0x1F, 0xFC, 0x0E, 0x1F, 0xF8, 0x70, 0x3F, 0xFE, 0x0F, 0x1F, 0xFC, 0x70, 0x7F,
+ 0xFF, 0xEF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x1F, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static const uint8_t WI48_THUNDERSTORM[] = {
- 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F,
- 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0,
- 0x3F, 0x81, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xFF,
- 0xFF, 0xC1, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xC1, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xF8,
- 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xC3, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0x03,
- 0xFC, 0x0F, 0xFF, 0xFF, 0xFC, 0x03, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, 0x03, 0xFC, 0x00, 0x0F, 0xFF,
- 0xE0, 0x1F, 0xFE, 0x00, 0x03, 0xFF, 0xE0, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xC1, 0xFF, 0xFF, 0xFE,
- 0x01, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0x83, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0x07, 0xFF,
- 0xFC, 0x07, 0xFF, 0xFF, 0x07, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x0F, 0xFF, 0xFC, 0x00, 0x07, 0xFF,
- 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0x0F, 0xFF, 0xFF, 0xFF,
- 0x00, 0x03, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0x07, 0xFF, 0xFD, 0xFF, 0xFF, 0x03, 0x07, 0xFF,
- 0xFC, 0x7F, 0x9F, 0xFF, 0x87, 0xFF, 0xFC, 0x1F, 0x8F, 0xFF, 0x83, 0xFF, 0xFC, 0x07, 0x83, 0xFF,
- 0x81, 0xFF, 0xFC, 0x01, 0x81, 0xFF, 0xC0, 0xFF, 0xFC, 0x00, 0x80, 0x7F, 0xE0, 0x7F, 0xFC, 0x00,
- 0x00, 0x3F, 0xF0, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x03, 0xFE, 0x00, 0x04, 0x07, 0xFC, 0x03,
- 0xFF, 0xC0, 0x07, 0xC1, 0xFF, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xC1, 0xFF, 0xF0, 0x07, 0xFF,
- 0xFF, 0xE1, 0xFF, 0xF0, 0xC7, 0xFF, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xC1,
- 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC,
- 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xC0, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xFF, 0xFF, 0xE0, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF,
+ 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x01, 0xFF,
+ 0xFE, 0x07, 0xFF, 0xFF, 0x00, 0x7F, 0xF8, 0x07, 0xFF, 0xFF, 0x00, 0x1F, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x0F,
+ 0xE0, 0x7F, 0xFF, 0xFF, 0xFE, 0x07, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
+ 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1,
+ 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x87, 0xF8, 0x0F, 0x9F, 0xBF, 0xE1, 0x87, 0xF8, 0x1F, 0x0F, 0x1F, 0xE1,
+ 0xC7, 0xF0, 0x1F, 0x1E, 0x1F, 0xE3, 0xC3, 0xF0, 0x3F, 0x1E, 0x1F, 0xC3, 0xC1, 0xE0, 0x3E, 0x1E, 0x3F, 0x83,
+ 0xE0, 0xE0, 0x7E, 0x1E, 0x3F, 0x07, 0xF0, 0x60, 0x7E, 0x3C, 0x3E, 0x0F, 0xF8, 0x00, 0xFE, 0x3C, 0x30, 0x1F,
+ 0xFC, 0x00, 0xFC, 0x3C, 0x70, 0x3F, 0xFF, 0x01, 0xFC, 0x3C, 0x70, 0x7F, 0xFF, 0x81, 0xFC, 0x78, 0x7F, 0xFF,
+ 0xFF, 0x80, 0x1C, 0x78, 0x7F, 0xFF, 0xFF, 0x00, 0x18, 0x78, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x78, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0x78, 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x78, 0xF9, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xF1, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xE7, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
diff --git a/scripts/convert_icon.py b/scripts/convert_icon.py
index 56ea7d4b..81585636 100644
--- a/scripts/convert_icon.py
+++ b/scripts/convert_icon.py
@@ -3,36 +3,113 @@ import os
from PIL import Image
import cairosvg
import io
+import xml.etree.ElementTree as ET
threshold = 128
+
+def parse_svg_intrinsic_size(svg_data):
+ try:
+ root = ET.fromstring(svg_data)
+ except ET.ParseError:
+ return None, None
+
+ viewbox = root.get("viewBox") or root.get("viewbox")
+ if viewbox:
+ parts = viewbox.replace(",", " ").split()
+ if len(parts) == 4:
+ try:
+ vb_w = float(parts[2])
+ vb_h = float(parts[3])
+ if vb_w > 0 and vb_h > 0:
+ return vb_w, vb_h
+ except ValueError:
+ pass
+
+ def parse_len(value):
+ if not value:
+ return None
+ cleaned = "".join(ch for ch in value if ch.isdigit() or ch in ".-")
+ if not cleaned:
+ return None
+ try:
+ parsed = float(cleaned)
+ return parsed if parsed > 0 else None
+ except ValueError:
+ return None
+
+ w = parse_len(root.get("width"))
+ h = parse_len(root.get("height"))
+ return w, h
+
+
+def fit_inside_canvas(src_w, src_h, dst_w, dst_h):
+ if src_w <= 0 or src_h <= 0 or dst_w <= 0 or dst_h <= 0:
+ return dst_w, dst_h
+
+ src_ratio = src_w / src_h
+ dst_ratio = dst_w / dst_h
+
+ if src_ratio >= dst_ratio:
+ fit_w = dst_w
+ fit_h = max(1, int(round(fit_w / src_ratio)))
+ else:
+ fit_h = dst_h
+ fit_w = max(1, int(round(fit_h * src_ratio)))
+
+ return fit_w, fit_h
+
+
def svg_to_png_bytes(svg_path, width, height):
- with open(svg_path, 'rb') as f:
+ with open(svg_path, "rb") as f:
svg_data = f.read()
- png_bytes = cairosvg.svg2png(bytestring=svg_data, output_width=width, output_height=height)
+
+ src_w, src_h = parse_svg_intrinsic_size(svg_data)
+ render_w, render_h = fit_inside_canvas(
+ src_w or width, src_h or height, width, height
+ )
+
+ png_bytes = cairosvg.svg2png(
+ bytestring=svg_data, output_width=render_w, output_height=render_h
+ )
return png_bytes
+
+def center_on_canvas(img, width, height):
+ if img.mode != "RGBA":
+ img = img.convert("RGBA")
+ canvas = Image.new("RGBA", (width, height), (255, 255, 255, 255))
+ x = (width - img.width) // 2
+ y = (height - img.height) // 2
+ canvas.paste(img, (x, y), img)
+ return canvas
+
+
def load_image(path, width, height):
ext = os.path.splitext(path)[1].lower()
- if ext == '.svg':
+ if ext == ".svg":
png_bytes = svg_to_png_bytes(path, width, height)
- img = Image.open(io.BytesIO(png_bytes))
+ img = Image.open(io.BytesIO(png_bytes)).convert("RGBA")
+ img = center_on_canvas(img, width, height)
else:
- img = Image.open(path)
- img = img.convert('RGBA')
- img = img.resize((width, height), Image.LANCZOS)
+ img = Image.open(path).convert("RGBA")
+ # Keep source aspect ratio and fit inside requested canvas.
+ fit = img.copy()
+ fit.thumbnail((width, height), Image.LANCZOS)
+ img = center_on_canvas(fit, width, height)
# Flatten alpha: paste on white background
- background = Image.new('RGBA', img.size, (255, 255, 255, 255))
+ background = Image.new("RGBA", img.size, (255, 255, 255, 255))
background.paste(img, mask=img.split()[3])
img = background
# Rotate 90 degrees counterclockwise
img = img.rotate(90, expand=True)
return img
+
def image_to_c_array(img, array_name):
# Convert to grayscale, then threshold to get white=1, black=0
# Convert to grayscale
- img = img.convert('L')
+ img = img.convert("L")
width, height = img.size
pixels = list(img.getdata())
packed = []
@@ -44,37 +121,39 @@ def image_to_c_array(img, array_name):
v = pixels[y * width + x + b]
# 1 for white, 0 for black
bit = 1 if v >= threshold else 0
- byte |= (bit << (7 - b))
+ byte |= bit << (7 - b)
packed.append(byte)
# Format as C array
- c = f'#pragma once\n#include \n\n'
- c += f'// size: {width}x{height}\n'
- c += f'static const uint8_t {array_name}[] = {{\n '
+ c = f"#pragma once\n#include \n\n"
+ c += f"// size: {width}x{height}\n"
+ c += f"static const uint8_t {array_name}[] = {{\n "
for i, v in enumerate(packed):
- c += f'0x{v:02X}, '
+ c += f"0x{v:02X}, "
if (i + 1) % 16 == 0:
- c += '\n '
- c = c.rstrip(', \n') + '\n};\n'
+ c += "\n "
+ c = c.rstrip(", \n") + "\n};\n"
return c
+
def main():
if len(sys.argv) < 5:
- print('Usage: python convert_image.py input.png output_name width height')
+ print("Usage: python convert_image.py input.png output_name width height")
sys.exit(1)
input_path, output_name, width, height = sys.argv[1:5]
- array_name = output_name.capitalize() + 'Icon'
+ array_name = output_name.capitalize() + "Icon"
width, height = int(width), int(height)
img = load_image(input_path, width, height)
c_array = image_to_c_array(img, array_name)
# Always save to src/components/icons/[output_name].h relative to project root
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- output_dir = os.path.join(project_root, 'src', 'components', 'icons')
+ output_dir = os.path.join(project_root, "src", "components", "icons")
os.makedirs(output_dir, exist_ok=True)
- output_path = os.path.join(output_dir, f'{output_name}.h')
- with open(output_path, 'w') as f:
+ output_path = os.path.join(output_dir, f"{output_name}.h")
+ with open(output_path, "w") as f:
f.write(c_array)
- print(f'Wrote {output_path}')
+ print(f"Wrote {output_path}")
-if __name__ == '__main__':
- main()
\ No newline at end of file
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/generate_weather_icons.py b/scripts/generate_weather_icons.py
new file mode 100644
index 00000000..c1ef2cb0
--- /dev/null
+++ b/scripts/generate_weather_icons.py
@@ -0,0 +1,277 @@
+#!/usr/bin/env python3
+"""
+Generate lib/Weather/WeatherIcons48.h from SVG sources.
+
+By default, this script loads SVG files from assets/weather-icons/svg.
+Use --fetch to download missing files from erikflowers/weather-icons.
+"""
+
+import argparse
+import io
+import os
+from pathlib import Path
+import shutil
+import subprocess
+import tempfile
+import urllib.request
+import xml.etree.ElementTree as ET
+import zipfile
+
+from PIL import Image
+
+try:
+ import cairosvg # type: ignore
+except Exception:
+ cairosvg = None
+
+
+SIZE = 48
+THRESHOLD = 128
+CONTENT_MARGIN = 1
+PROJECT_ROOT = Path(__file__).resolve().parent.parent
+DEFAULT_SVG_DIR = PROJECT_ROOT / "assets" / "weather-icons" / "svg"
+DEFAULT_OUT = PROJECT_ROOT / "lib" / "Weather" / "WeatherIcons48.h"
+UPSTREAM_BASE = "https://raw.githubusercontent.com/erikflowers/weather-icons/master/svg"
+RESVG_ZIP_URL = (
+ "https://github.com/linebender/resvg/releases/latest/download/resvg-win64.zip"
+)
+RESVG_EXE = PROJECT_ROOT / ".cache" / "resvg" / "resvg.exe"
+
+ICON_SOURCES = {
+ "WI48_CLEAR_DAY": "wi-day-sunny.svg",
+ "WI48_CLEAR_NIGHT": "wi-night-clear.svg",
+ "WI48_PARTLY_CLOUDY_DAY": "wi-day-cloudy.svg",
+ "WI48_PARTLY_CLOUDY_NIGHT": "wi-night-alt-cloudy.svg",
+ "WI48_OVERCAST": "wi-cloudy.svg",
+ "WI48_FOG": "wi-fog.svg",
+ "WI48_DRIZZLE": "wi-sprinkle.svg",
+ "WI48_RAIN": "wi-rain.svg",
+ "WI48_SNOW": "wi-snow.svg",
+ "WI48_THUNDERSTORM": "wi-thunderstorm.svg",
+}
+
+
+def parse_svg_intrinsic_size(svg_data):
+ try:
+ root = ET.fromstring(svg_data)
+ except ET.ParseError:
+ return None, None
+
+ viewbox = root.get("viewBox") or root.get("viewbox")
+ if viewbox:
+ parts = viewbox.replace(",", " ").split()
+ if len(parts) == 4:
+ try:
+ vb_w = float(parts[2])
+ vb_h = float(parts[3])
+ if vb_w > 0 and vb_h > 0:
+ return vb_w, vb_h
+ except ValueError:
+ pass
+
+ def parse_len(value):
+ if not value:
+ return None
+ cleaned = "".join(ch for ch in value if ch.isdigit() or ch in ".-")
+ if not cleaned:
+ return None
+ try:
+ parsed = float(cleaned)
+ return parsed if parsed > 0 else None
+ except ValueError:
+ return None
+
+ return parse_len(root.get("width")), parse_len(root.get("height"))
+
+
+def fit_inside_canvas(src_w, src_h, dst_w, dst_h):
+ if src_w <= 0 or src_h <= 0:
+ return dst_w, dst_h
+
+ src_ratio = src_w / src_h
+ dst_ratio = dst_w / dst_h
+ if src_ratio >= dst_ratio:
+ fit_w = dst_w
+ fit_h = max(1, int(round(fit_w / src_ratio)))
+ else:
+ fit_h = dst_h
+ fit_w = max(1, int(round(fit_h * src_ratio)))
+ return fit_w, fit_h
+
+
+def ensure_resvg_binary():
+ if shutil.which("resvg"):
+ return Path(shutil.which("resvg"))
+
+ if RESVG_EXE.exists():
+ return RESVG_EXE
+
+ RESVG_EXE.parent.mkdir(parents=True, exist_ok=True)
+ archive_path = RESVG_EXE.parent / "resvg.zip"
+ with urllib.request.urlopen(RESVG_ZIP_URL) as response:
+ archive_path.write_bytes(response.read())
+
+ with zipfile.ZipFile(archive_path, "r") as zf:
+ zf.extractall(RESVG_EXE.parent)
+
+ found = list(RESVG_EXE.parent.rglob("resvg.exe"))
+ if not found:
+ raise RuntimeError("resvg.exe not found after extraction")
+
+ if found[0] != RESVG_EXE:
+ RESVG_EXE.write_bytes(found[0].read_bytes())
+
+ return RESVG_EXE
+
+
+def render_svg_with_resvg(svg_data, render_w, render_h):
+ exe = ensure_resvg_binary()
+ with tempfile.TemporaryDirectory() as tmp:
+ tmp_path = Path(tmp)
+ in_svg = tmp_path / "icon.svg"
+ out_png = tmp_path / "icon.png"
+ in_svg.write_bytes(svg_data)
+
+ cmd = [
+ str(exe),
+ "--width",
+ str(render_w),
+ "--height",
+ str(render_h),
+ str(in_svg),
+ str(out_png),
+ ]
+ subprocess.run(cmd, check=True, capture_output=True)
+ return out_png.read_bytes()
+
+
+def render_svg_contain(svg_data, width, height):
+ src_w, src_h = parse_svg_intrinsic_size(svg_data)
+ render_w, render_h = fit_inside_canvas(
+ src_w or width, src_h or height, width, height
+ )
+
+ # Render larger first so trimming and re-fit preserve detail quality.
+ oversample = 4
+ render_w *= oversample
+ render_h *= oversample
+
+ if cairosvg is not None:
+ png_bytes = cairosvg.svg2png(
+ bytestring=svg_data, output_width=render_w, output_height=render_h
+ )
+ else:
+ png_bytes = render_svg_with_resvg(svg_data, render_w, render_h)
+
+ icon = Image.open(io.BytesIO(png_bytes)).convert("RGBA")
+
+ # Trim transparent/empty margins so symbols use available icon area better.
+ alpha_bbox = icon.split()[3].getbbox()
+ if alpha_bbox is not None:
+ icon = icon.crop(alpha_bbox)
+
+ max_w = max(1, width - 2 * CONTENT_MARGIN)
+ max_h = max(1, height - 2 * CONTENT_MARGIN)
+ icon.thumbnail((max_w, max_h), Image.Resampling.LANCZOS)
+
+ canvas = Image.new("RGBA", (width, height), (255, 255, 255, 255))
+ off_x = (width - icon.width) // 2
+ off_y = (height - icon.height) // 2
+ canvas.paste(icon, (off_x, off_y), icon)
+
+ # Flatten alpha on white and convert to monochrome-friendly grayscale.
+ flat = Image.new("RGBA", canvas.size, (255, 255, 255, 255))
+ flat.paste(canvas, mask=canvas.split()[3])
+ return flat.convert("L")
+
+
+def image_to_packed_bits(img):
+ width, height = img.size
+ pixels = img.tobytes()
+ packed = []
+ for y in range(height):
+ for x in range(0, width, 8):
+ out = 0
+ for b in range(8):
+ px = x + b
+ lum = pixels[y * width + px] if px < width else 255
+ # 1-bit means white/clear (not drawn), 0-bit means black/drawn.
+ bit = 1 if lum >= THRESHOLD else 0
+ out |= bit << (7 - b)
+ packed.append(out)
+ return packed
+
+
+def format_array(name, data):
+ lines = []
+ per_line = 16
+ for i in range(0, len(data), per_line):
+ chunk = data[i : i + per_line]
+ lines.append(" " + ", ".join(f"0x{v:02X}" for v in chunk) + ",")
+ body = "\n".join(lines)
+ return f"static const uint8_t {name}[] = {{\n{body}\n}};\n"
+
+
+def ensure_svg(path, fetch):
+ if path.exists():
+ return
+ if not fetch:
+ raise FileNotFoundError(f"Missing SVG: {path}")
+
+ path.parent.mkdir(parents=True, exist_ok=True)
+ url = f"{UPSTREAM_BASE}/{path.name}"
+ with urllib.request.urlopen(url) as response:
+ data = response.read()
+ path.write_bytes(data)
+
+
+def generate(svg_dir, output_path, fetch):
+ arrays = []
+ for symbol, filename in ICON_SOURCES.items():
+ svg_path = svg_dir / filename
+ ensure_svg(svg_path, fetch)
+ svg_data = svg_path.read_bytes()
+ img = render_svg_contain(svg_data, SIZE, SIZE)
+ packed = image_to_packed_bits(img)
+ arrays.append(format_array(symbol, packed))
+
+ header = [
+ "#pragma once",
+ "#include ",
+ "",
+ "// Generated from erikflowers/weather-icons SVGs.",
+ "// 48x48, 1-bit, MSB-first, row-major.",
+ "// Regenerate with: python scripts/generate_weather_icons.py --fetch",
+ "",
+ ]
+ header.extend(arrays)
+
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ output_path.write_text("\n".join(header) + "\n", encoding="utf-8")
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Generate WeatherIcons48.h from SVG files"
+ )
+ parser.add_argument(
+ "--svg-dir",
+ type=Path,
+ default=DEFAULT_SVG_DIR,
+ help="Directory containing source SVG files",
+ )
+ parser.add_argument(
+ "--output", type=Path, default=DEFAULT_OUT, help="Output header path"
+ )
+ parser.add_argument(
+ "--fetch", action="store_true", help="Fetch missing SVG files from upstream"
+ )
+ args = parser.parse_args()
+
+ generate(args.svg_dir, args.output, args.fetch)
+ rel_out = os.path.relpath(args.output, PROJECT_ROOT)
+ print(f"Wrote {rel_out}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/activities/weather/WeatherActivity.cpp b/src/activities/weather/WeatherActivity.cpp
index d5183b36..5c4502cb 100644
--- a/src/activities/weather/WeatherActivity.cpp
+++ b/src/activities/weather/WeatherActivity.cpp
@@ -9,7 +9,6 @@
#include
#include
-#include
#include
#include
#include
@@ -29,79 +28,18 @@ inline bool getBitmapBit(const uint8_t* bitmap, const int size, const int x, con
return (bitmap[idx] & mask) != 0;
}
-inline void setBitmapBit(uint8_t* bitmap, const int size, const int x, const int y, const bool value) {
- const int rowBytes = size / 8;
- const int idx = y * rowBytes + (x / 8);
- const uint8_t mask = static_cast(0x80 >> (x % 8));
- if (value) {
- bitmap[idx] |= mask;
- } else {
- bitmap[idx] &= static_cast(~mask);
- }
-}
-
void drawWeatherIconWithOrientation(const GfxRenderer& renderer, const uint8_t* icon, const int x, const int y,
const int size) {
- // Weather activity uses LandscapeClockwise; rotate icon pixels 90deg so
- // directional glyphs align with the landscape-oriented UI.
- if (renderer.getOrientation() != GfxRenderer::Orientation::LandscapeClockwise) {
- renderer.drawImage(icon, x, y, size, size);
- return;
- }
-
- constexpr int kLargeIconBytes = (WEATHER_ICON_LARGE * WEATHER_ICON_LARGE) / 8;
- std::array rotatedRaw{};
- rotatedRaw.fill(0xFF);
-
for (int srcY = 0; srcY < size; srcY++) {
for (int srcX = 0; srcX < size; srcX++) {
- // 90deg counter-clockwise: (x, y) -> (y, size - 1 - x)
- const int dstX = srcY;
- const int dstY = size - 1 - srcX;
- setBitmapBit(rotatedRaw.data(), size, dstX, dstY, getBitmapBit(icon, size, srcX, srcY));
- }
- }
-
- // Re-center rotated icon by its painted-pixel bounds to avoid asymmetric
- // source padding appearing as left-side clipping after rotation.
- int minX = size, minY = size, maxX = -1, maxY = -1;
- for (int py = 0; py < size; py++) {
- for (int px = 0; px < size; px++) {
- if (!getBitmapBit(rotatedRaw.data(), size, px, py)) {
- minX = std::min(minX, px);
- minY = std::min(minY, py);
- maxX = std::max(maxX, px);
- maxY = std::max(maxY, py);
- }
- }
- }
-
- if (maxX < minX || maxY < minY) {
- renderer.drawImage(rotatedRaw.data(), x, y, size, size);
- return;
- }
-
- const int bboxW = maxX - minX + 1;
- const int bboxH = maxY - minY + 1;
- const int targetMinX = (size - bboxW) / 2;
- const int targetMinY = (size - bboxH) / 2;
- const int shiftX = targetMinX - minX;
- const int shiftY = targetMinY - minY;
-
- std::array rotatedCentered{};
- rotatedCentered.fill(0xFF);
- for (int py = 0; py < size; py++) {
- for (int px = 0; px < size; px++) {
- const int dstX = px + shiftX;
- const int dstY = py + shiftY;
- if (dstX < 0 || dstX >= size || dstY < 0 || dstY >= size) {
+ // 0 bits are black (drawn) in these icon bitmaps.
+ if (getBitmapBit(icon, size, srcX, srcY)) {
continue;
}
- setBitmapBit(rotatedCentered.data(), size, dstX, dstY, getBitmapBit(rotatedRaw.data(), size, px, py));
+
+ renderer.drawPixel(x + srcX, y + srcY);
}
}
-
- renderer.drawImage(rotatedCentered.data(), x, y, size, size);
}
StrId getWeatherDescriptionStrId(const int wmoCode) {
@@ -193,6 +131,8 @@ void WeatherActivity::onExit() {
}
void WeatherActivity::loadAndDisplay() {
+ constexpr long CACHE_REFRESH_AGE_SECONDS = 30L * 60L;
+
if (!WEATHER_SETTINGS.hasLocation()) {
state = State::ERROR;
errorMessage = tr(STR_WEATHER_NO_LOCATION);
@@ -203,23 +143,23 @@ void WeatherActivity::loadAndDisplay() {
// Try cache first
WeatherData cached = WeatherClient::getWeather(WEATHER_SETTINGS, forceRefresh);
if (cached.valid) {
- const bool shouldRefresh = forceRefresh;
- if (!shouldRefresh) {
- const time_t now = time(nullptr);
- const long age = (cached.fetchedAt > 0) ? static_cast(now - cached.fetchedAt) : -1;
- if (age >= 0 && age > 30L * 60L) {
- LOG_DBG("WEA", "Displayed stale cache (age=%ld s); scheduling refresh", age);
- } else {
- LOG_DBG("WEA", "Displayed cache (age=%ld s)", age);
- }
+ const time_t now = time(nullptr);
+ const long age = (cached.fetchedAt > 0) ? static_cast(now - cached.fetchedAt) : -1;
+ const bool cacheIsStale = (age >= 0 && age > CACHE_REFRESH_AGE_SECONDS) || age < 0;
+ const bool shouldBackgroundRefresh = forceRefresh || cacheIsStale;
+
+ if (cacheIsStale) {
+ LOG_DBG("WEA", "Displayed stale cache (age=%ld s); scheduling refresh", age);
+ } else {
+ LOG_DBG("WEA", "Displayed fresh cache (age=%ld s); skip auto-refresh", age);
}
weatherData = std::move(cached);
state = State::WEATHER_DISPLAY;
requestUpdate();
- // After first paint, refresh stale/non-forced data via WiFi-gated path.
- if (!forceRefresh) {
+ // Refresh only when forced or when cache is stale.
+ if (shouldBackgroundRefresh) {
checkAndConnectWifi();
}
return;
@@ -300,6 +240,7 @@ void WeatherActivity::loop() {
if (state == State::ERROR) {
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
// Open weather settings (useful when no location is configured)
+ renderer.setOrientation(GfxRenderer::Orientation::Portrait);
startActivityForResult(std::make_unique(renderer, mappedInput),
[this](const ActivityResult&) {
renderer.setOrientation(GfxRenderer::Orientation::LandscapeClockwise);
@@ -359,6 +300,7 @@ void WeatherActivity::loop() {
onGoHome();
} else if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
// Open weather settings
+ renderer.setOrientation(GfxRenderer::Orientation::Portrait);
startActivityForResult(std::make_unique(renderer, mappedInput),
[this](const ActivityResult&) {
// Re-apply landscape after returning from settings