├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── examples
├── 2x1Screens
│ ├── text
│ │ ├── text.ino
│ │ └── xtrchr30pt7b.h
│ └── text_circle_animation
│ │ ├── text_circle_animation.ino
│ │ └── xtrchr30pt7b.h
├── 2x2Screens
│ ├── breakout
│ │ └── breakout.ino
│ └── image
│ │ ├── image.ino
│ │ ├── spacedock_480x480.h
│ │ └── spaceship_480x480.h
├── 3x3Screens
│ └── clocks
│ │ ├── SecondWorldDemoRegular40pt7b.h
│ │ ├── clock_1.h
│ │ ├── clock_2.h
│ │ ├── clock_3.h
│ │ └── clocks.ino
└── 4x1Screens
│ ├── ballcourt
│ ├── ballcourt.h
│ └── ballcourt.ino
│ ├── font_test
│ ├── Star_Trek_Enterprise_Future80pt7b.h
│ ├── Starjedi32pt7b.h
│ ├── font_test.ino
│ └── raidercrusader48pt7b.h
│ ├── gameoflife
│ ├── BebasNeue_Regular13pt7b.h
│ └── gameoflife.ino
│ ├── image
│ ├── image.ino
│ ├── newyork_960x240.h
│ └── night_earth_960x240.h
│ ├── maze
│ └── maze.ino
│ ├── pong
│ ├── Fun_Games20pt7b.h
│ ├── Fun_Games40pt7b.h
│ └── pong.ino
│ └── tetris
│ └── tetris.ino
├── font_test.h
├── fonts
├── Aurebesh_Bold32pt7b.h
├── BebasNeue_Regular13pt7b.h
├── Bombing40pt7b.h
├── Fun_Games20pt7b.h
├── Fun_Games40pt7b.h
├── SecondWorldDemoRegular40pt7b.h
├── Star_Trek_Enterprise_Future80pt7b.h
├── Starjedi32pt7b.h
├── raidercrusader48pt7b.h
└── xtrchr30pt7b.h
├── image_test.h
├── images
├── ballcourt.h
├── bazar_960x240.h
├── clock_1.h
├── clock_2.h
├── clock_3.h
├── console_960x240.h
├── highway_720x480.h
├── spacebattle_960x240.h
├── spacedock_480x480.h
└── spaceship_480x480.h
├── keywords.txt
├── library.properties
├── oldino
├── src
└── virtualScreen.h
└── virtualScreen.ino
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | custom: https://www.buymeacoffee.com/thelastoutpostworkshop
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | sounds
3 | secrets.h
4 | .vscode
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 thelastoutpostworkshop
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VirtualScreen: An Arduino Library for Auto-Spanning Adafruit GFX Graphics Across Multiple Displays / Screens
2 |
3 | **Seamlessly Integrate Multiple Displays with Ease: A User-Friendly Approach to Expansive Graphics**.
4 |
5 |
6 |
7 |
8 |
9 | ## Youtube Tutorial
10 | [
](https://youtu.be/eCfeJh9Pyns)
11 |
12 | ## Installation
13 | ### Installation Arduino IDE (Version 2)
14 |
15 | - Install the **VirtualDisplay Library with the Arduino IDE Library Manager**, it will also install the [TFT_eSPI library](https://github.com/Bodmer/TFT_eSPI) serving as driver for the displays.
16 |
17 |
18 | ## Usage
19 | >ℹ️ There are many examples and display layout included with the library `File > Examples > VirtualDisplay`
20 | ```c
21 | #include
22 |
23 | VirtualDisplay *tft;
24 | ScreenBuilder screens;
25 |
26 | void setup()
27 | {
28 | Serial.begin(115200);
29 |
30 | // Adjust this setup according to your actual screen configuration
31 | screens.addRow({{6, 0}, {7, 0}});
32 |
33 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
34 | tft->begin();
35 |
36 | // Use any Adafruit GFX Graphics functions
37 | tft->setTextColor(TFT_CYAN);
38 | tft->setCursor(0,90);
39 | tft->print("Virtual Display");
40 |
41 | tft->output(); // Use this function to output the result on the screens
42 | }
43 | ```
44 | ## Display Layout
45 | >ℹ️ You can only use display of the same resolution
46 |
47 | Add rows of screens (display) by using the ``` addRow() ``` function.
48 | A screen is definded by ``` {int chip_select_pin, int rotation} ```
49 | ```screens.addRow({{6, 0}, {7, 0}}); ``` adds a row of two screens of rotation 0, the first screen has a chip select on pin 6, and the other has the chip select on pin 7.
50 |
51 | ## Driver Setup for your Display
52 | - You have to setup the driver in the [TFT_eSPI library](https://github.com/Bodmer/TFT_eSPI) configuration files for your display type, see my tutorial on how to do it.
53 |
54 | ## Display supported
55 | - Any 16 bit-color display supported by the [TFT_eSPI library](https://github.com/Bodmer/TFT_eSPI)
56 |
57 | ## Recommended ESP32
58 | - Spanning graphics across multiple displays requires a fair amount of memory, use an **ESP32 with PSRAM**.
59 | - The [ESP32-S3 N16R2](https://amzn.to/3TsziTh) is a good choice.
60 |
61 | ## Graphics functions
62 | >ℹ️ You can use any graphics functions from the [Adafruit GFX library](https://learn.adafruit.com/adafruit-gfx-graphics-library/graphics-primitives)
63 | Here are other graphics functions built in the VirtualScreen Library :
64 |
65 | | Graphics functions | Description |
66 | |---------|-------------|
67 | |output() | Output to the screens according to your screen layout |
68 | |highlightArea(int16_t x, int16_t y, int16_t width, int16_t height, float intensity) | Highlight a specified area of the canvas with adjustable intensity |
69 | |highlightArea(int16_t centerX, int16_t centerY, int16_t radius, float intensity) | Highlight a circular area of the canvas with adjustable intensity |
70 | |color565(uint8_t r, uint8_t g, uint8_t b) | Convert RGB Color to a 565 color code |
71 | |readRect(int16_t x, int16_t y, int16_t width, int16_t height, uint16_t *buffer) | Read an image area into buffer (must be allocated before calling the function) |
72 |
73 |
74 | ## Performance
75 | The library will redraw a display only if its content has changed, so avoid redrawing the entire canvas if you can.
76 |
77 | ## Contributors
78 | Contributors are welcomed! If you want to submit pull requests, [here is how you can do it](https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-a-project).
79 |
--------------------------------------------------------------------------------
/examples/2x1Screens/text/text.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 2 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include
6 | #include "xtrchr30pt7b.h"
7 |
8 | VirtualDisplay *tft;
9 | ScreenBuilder screens;
10 |
11 | void setup()
12 | {
13 | Serial.begin(115200);
14 |
15 | // Adjust this setup according to your actual screen layout
16 | screens.addRow({{6, 0}, {7, 0}});
17 |
18 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
19 | tft->begin();
20 |
21 | tft->setFont(&xtrchr30pt7b);
22 | tft->setTextColor(TFT_CYAN);
23 | tft->setCursor(0,90);
24 | tft->print("Virtual Display");
25 | tft->output();
26 | }
27 |
28 | void loop()
29 | {
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/examples/2x1Screens/text_circle_animation/text_circle_animation.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 2 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "xtrchr30pt7b.h"
7 |
8 | VirtualDisplay *tft;
9 | ScreenBuilder screens;
10 |
11 | void setup()
12 | {
13 | Serial.begin(115200);
14 |
15 | // Adjust this setup according to your actual screen layout
16 | screens.addRow({{6, 0}, {7, 0}});
17 |
18 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
19 | tft->begin();
20 |
21 | tft->setFont(&xtrchr30pt7b);
22 | tft->fillScreen(0xfaa0);
23 | tft->drawRoundRect(10, 10, tft->width() - 20, tft->height() - 20, 25, TFT_CYAN);
24 | tft->drawRoundRect(20, 20, tft->width() - 40, tft->height() - 40, 25, TFT_CYAN);
25 | tft->setTextColor(TFT_CYAN);
26 | tft->setCursor(80, 140);
27 | tft->print("Amazing!");
28 | tft->output();
29 | }
30 |
31 | void loop()
32 | {
33 | static bool toggleColor = false;
34 | tft->fillCircle(400, tft->height()/2, 30, toggleColor ? TFT_YELLOW : 0xfaa0);
35 | tft->output();
36 | delay(400);
37 | toggleColor = !toggleColor;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/2x2Screens/breakout/breakout.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 2x2 Grid, two screens on each row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 |
7 | VirtualDisplay *tft;
8 | ScreenBuilder screens;
9 |
10 | void setup()
11 | {
12 | Serial.begin(115200);
13 |
14 | // Adjust this setup according to your actual screen layout
15 | screens.addRow({{6, 0}, {7, 0}});
16 | screens.addRow({{16, 2}, {15, 2}});
17 |
18 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
19 | tft->begin();
20 |
21 | tft->fillScreen(TFT_BLACK);
22 | tft->output();
23 | setupGame();
24 | }
25 |
26 | void loop()
27 | {
28 | updateGame();
29 | drawBricks();
30 | drawPaddle();
31 | drawBall();
32 |
33 | tft->output();
34 | }
35 |
36 | // Game settings
37 | const int paddleWidth = 40;
38 | const int paddleHeight = 15;
39 | const int ballRadius = 10;
40 | const int brickWidth = 40;
41 | const int brickHeight = 20;
42 | const int numRows = 7;
43 | const int numCols = 10; // Adjust based on your display size
44 |
45 | // Game state
46 | int paddleX;
47 | int ballX, ballY;
48 | int ballVelocityX = 10, ballVelocityY = -10;
49 | bool bricks[numRows][numCols]; // True if the brick is still there
50 |
51 | int prevPaddleX;
52 | int prevBallX, prevBallY;
53 | bool prevBricks[numRows][numCols]; // To track changes in bricks
54 |
55 | // Initialize game state
56 | void setupGame()
57 | {
58 | paddleX = prevPaddleX = (tft->width() - paddleWidth) / 2;
59 | ballX = prevBallX = tft->width() / 2;
60 | ballY = prevBallY = tft->height() - 30; // Start the ball above the paddle
61 | memset(bricks, true, sizeof(bricks)); // Initialize all bricks as visible
62 |
63 | // Initially mark all previous bricks as not present to ensure they are drawn initially
64 | memset(prevBricks, false, sizeof(prevBricks)); // Force drawing of all bricks initially
65 |
66 | // Draw initial game state
67 | drawBricks(); // Draw all bricks initially
68 | drawPaddle();
69 | drawBall();
70 | tft->output(); // Update the display after initial setup
71 | }
72 |
73 | uint16_t calculateRowColor(int row, int totalRows) {
74 | // Define the midpoint for the transition from red to orange, then orange to green
75 | float midpoint = 0.5f;
76 | float progress = (float)row / (totalRows - 1); // Progress from 0.0 (top) to 1.0 (bottom)
77 |
78 | uint8_t red, green;
79 |
80 | // Calculate the RGB components based on the row's position
81 | if (progress <= midpoint) {
82 | // Transition from red to orange in the first half
83 | red = 31; // Maximum red value for the entire first half
84 | green = (progress / midpoint) * 31; // Scale green up to 31 (to get orange) at the midpoint
85 | } else {
86 | // Transition from orange to green in the second half
87 | red = (1.0f - (progress - midpoint) / midpoint) * 31; // Scale red down to 0 past the midpoint
88 | green = 31 + ((progress - midpoint) / midpoint) * (63 - 31); // Continue scaling green from 31 to 63
89 | }
90 |
91 | // Combine the components into a 16-bit color value
92 | return (red << 11) | (green << 5);
93 | }
94 |
95 | void drawPaddle()
96 | {
97 | // Clear the previous paddle position
98 | tft->fillRect(prevPaddleX, tft->height() - paddleHeight - 1, paddleWidth, paddleHeight, TFT_BLACK);
99 | // Draw the new paddle position
100 | tft->fillRect(paddleX, tft->height() - paddleHeight - 1, paddleWidth, paddleHeight, TFT_CYAN);
101 | prevPaddleX = paddleX; // Update the previous paddle position
102 | }
103 |
104 | void drawBall()
105 | {
106 | // Clear the previous ball position
107 | tft->fillCircle(prevBallX, prevBallY, ballRadius, TFT_BLACK);
108 | // Draw the new ball position
109 | tft->fillCircle(ballX, ballY, ballRadius, TFT_YELLOW);
110 | prevBallX = ballX; // Update the previous ball position
111 | prevBallY = ballY;
112 | }
113 |
114 | void drawBricks() {
115 | for (int row = 0; row < numRows; ++row) {
116 | // Calculate the color for the current row
117 | uint16_t rowColor = calculateRowColor(row, numRows);
118 |
119 | for (int col = 0; col < numCols; ++col) {
120 | // Draw only if the brick status has changed
121 | if (bricks[row][col] != prevBricks[row][col]) {
122 | int x = col * (brickWidth + 5);
123 | int y = row * (brickHeight + 5);
124 | if (bricks[row][col]) {
125 | tft->fillRect(x, y, brickWidth, brickHeight, rowColor); // Use the row-specific color
126 | } else {
127 | tft->fillRect(x, y, brickWidth, brickHeight, TFT_BLACK); // Clear the brick if it was hit
128 | }
129 | prevBricks[row][col] = bricks[row][col]; // Update the tracked brick status
130 | }
131 | }
132 | }
133 | }
134 |
135 |
136 | void updateGame()
137 | {
138 | // Move the paddle automatically by following the ball
139 | paddleX = ballX - paddleWidth / 2;
140 |
141 | // Update ball position
142 | ballX += ballVelocityX;
143 | ballY += ballVelocityY;
144 |
145 | // Collision detection with the walls
146 | if (ballX <= 0 || ballX >= tft->width())
147 | ballVelocityX = -ballVelocityX;
148 | if (ballY <= 0)
149 | ballVelocityY = -ballVelocityY;
150 |
151 | // Collision detection with the paddle
152 | int paddleTopY = tft->height() - paddleHeight - 1; // Y position of the top of the paddle
153 | if (ballY + ballVelocityY > paddleTopY - ballRadius && // Check if moving past the paddle's top edge
154 | ballY < paddleTopY + paddleHeight && // And is within paddle's height range
155 | ballX + ballVelocityX > paddleX - ballRadius && // Check if within paddle's left edge
156 | ballX + ballVelocityX < paddleX + paddleWidth + ballRadius)
157 | { // And within paddle's right edge
158 | ballVelocityY = -ballVelocityY; // Reverse Y direction
159 | ballY = paddleTopY - ballRadius; // Adjust ball position to avoid sticking or multiple collisions
160 | }
161 |
162 | // Collision detection with bricks
163 | for (int row = 0; row < numRows; ++row)
164 | {
165 | for (int col = 0; col < numCols; ++col)
166 | {
167 | if (bricks[row][col])
168 | { // If the brick is there
169 | int brickX = col * (brickWidth + 5);
170 | int brickY = row * (brickHeight + 5);
171 |
172 | // Expanded collision detection area to account for the ball's radius
173 | if (ballX + ballRadius > brickX && ballX - ballRadius < brickX + brickWidth &&
174 | ballY + ballRadius > brickY && ballY - ballRadius < brickY + brickHeight)
175 | {
176 |
177 | // Determine collision direction
178 | float middleX = brickX + brickWidth / 2;
179 | float middleY = brickY + brickHeight / 2;
180 | float deltaX = ballX - middleX;
181 | float deltaY = ballY - middleY;
182 |
183 | // Remove the brick
184 | bricks[row][col] = false;
185 |
186 | // Determine if collision is more horizontal or vertical
187 | // and reverse the appropriate velocity component
188 | if (fabs(deltaX) > fabs(deltaY))
189 | {
190 | if (ballX < middleX)
191 | { // Hit was from the left
192 | ballVelocityX = -abs(ballVelocityX);
193 | }
194 | else
195 | { // Hit was from the right
196 | ballVelocityX = abs(ballVelocityX);
197 | }
198 | }
199 | else
200 | {
201 | if (ballY < middleY)
202 | { // Hit was from above
203 | ballVelocityY = -abs(ballVelocityY);
204 | }
205 | else
206 | { // Hit was from below
207 | ballVelocityY = abs(ballVelocityY);
208 | }
209 | }
210 | }
211 | }
212 | }
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/examples/2x2Screens/image/image.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 2x2 Grid, two screens on each row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "spaceship_480x480.h"
7 | #include "spacedock_480x480.h"
8 |
9 | VirtualDisplay *tft;
10 | ScreenBuilder screens;
11 |
12 | void setup()
13 | {
14 | Serial.begin(115200);
15 |
16 | // Adjust this setup according to your actual screen layout
17 | screens.addRow({{6, 0}, {7, 0}});
18 | screens.addRow({{16, 2}, {15, 2}});
19 |
20 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
21 | tft->begin();
22 |
23 | tft->fillScreen(TFT_BLACK);
24 | tft->drawRGBBitmap(0, 0, (uint16_t *)spaceship_480x480, spaceship_480x480_width, spaceship_480x480_height);
25 | tft->output();
26 | delay(5000);
27 | tft->drawRGBBitmap(0, 0, (uint16_t *)spacedock_480x480, spacedock_480x480_width, spacedock_480x480_height);
28 | tft->output();
29 | }
30 |
31 | void loop()
32 | {
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/examples/3x3Screens/clocks/clocks.ino:
--------------------------------------------------------------------------------
1 | #include "virtualScreen.h"
2 | // Screen Layout : 3x2 Grid, three screens on each row
3 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
4 | //
5 |
6 | #include "clock_1.h"
7 | #include "clock_2.h"
8 | #include "clock_3.h"
9 | #include "SecondWorldDemoRegular40pt7b.h"
10 |
11 | VirtualDisplay *tft;
12 | ScreenBuilder screens;
13 |
14 | void setup()
15 | {
16 | Serial.begin(115200);
17 |
18 | // Adjust this setup according to your actual screen layout
19 | // 6 screens, 3 on each row
20 | screens.addRow({{7, 2}, {6, 2}, {15, 2}});
21 | screens.addRow({{16, 0}, {11, 0}, {9, 0}});
22 |
23 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
24 | tft->begin();
25 |
26 |
27 | tft->fillScreen(TFT_BLACK);
28 | tft->pushImage(0, 0, clock1_width, clock1_height, (uint16_t *)clock1);
29 | tft->pushImage(240, 0, clock2_width, clock2_height, (uint16_t *)clock2);
30 | tft->pushImage(480, 0, clock3_width, clock3_height, (uint16_t *)clock3);
31 | tft->setFont(&SecondWorldDemoRegular40pt7b);
32 | tft->setTextColor(0xef48);
33 | tft->setCursor(50, 385);
34 | tft->print("Very Strange Clocks");
35 | }
36 |
37 | unsigned long lastUpdateTime = 0;
38 | const long updateInterval = 1000; // Update every second
39 |
40 | void loop()
41 | {
42 | tft->highlightArea(360, 120, 50, 0.5f);
43 |
44 | tft->output();
45 | tft->pushImage(240, 0, clock2_width, clock2_height, (uint16_t *)clock2);
46 | tft->output();
47 |
48 | unsigned long currentMillis = millis();
49 | if (currentMillis - lastUpdateTime >= updateInterval)
50 | {
51 | lastUpdateTime = currentMillis;
52 |
53 | // Assuming you have a way to get the current time in seconds
54 | int seconds = (currentMillis / 1000) % 60; // Simulated for demonstration
55 |
56 | tft->pushImage(0, 0, clock1_width, clock1_height, (uint16_t *)clock1);
57 |
58 | // Draw the new seconds hand
59 | drawSecondsHand(seconds, TFT_RED); // White color for the hand
60 |
61 | tft->output(); // Update the display with the changes
62 | }
63 | }
64 |
65 | void drawSecondsHand(int seconds, uint16_t color) {
66 | float angle = (seconds - 15) * (2 * M_PI / 60); // Convert seconds to angle
67 | int16_t centerX = 120, centerY = 120; // Center of the clock
68 | int16_t length = 60; // Length of the seconds hand
69 |
70 | // Tip of the seconds hand
71 | int16_t endX = centerX + length * cos(angle);
72 | int16_t endY = centerY + length * sin(angle);
73 |
74 | // Width of the base of the triangle hand
75 | int16_t handWidth = 10;
76 |
77 | // Calculate the two additional points for the base of the triangle
78 | float baseAngle = angle + M_PI / 2; // Perpendicular to the hand direction
79 | int16_t baseOffsetX = handWidth * cos(baseAngle) / 2;
80 | int16_t baseOffsetY = handWidth * sin(baseAngle) / 2;
81 |
82 | int16_t basePoint1X = centerX + baseOffsetX;
83 | int16_t basePoint1Y = centerY + baseOffsetY;
84 | int16_t basePoint2X = centerX - baseOffsetX;
85 | int16_t basePoint2Y = centerY - baseOffsetY;
86 |
87 | // Define points array for triangle
88 | int16_t points[6] = {endX, endY, basePoint1X, basePoint1Y, basePoint2X, basePoint2Y};
89 |
90 | // Draw the triangle
91 | tft->fillTriangle(points[0], points[1], points[2], points[3], points[4], points[5], color);
92 | }
93 |
94 |
--------------------------------------------------------------------------------
/examples/4x1Screens/ballcourt/ballcourt.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "ballcourt.h"
7 |
8 | VirtualDisplay *tft;
9 |
10 | void setup()
11 | {
12 | Serial.begin(115200);
13 |
14 | ScreenBuilder screens;
15 | // Adjust this setup according to your actual screen layout
16 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
17 |
18 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
19 | tft->begin();
20 |
21 | // Start the bouncing ball animation
22 | runBouncingBall();
23 | }
24 |
25 | void loop()
26 | {
27 | }
28 |
29 | class BouncingBall
30 | {
31 | private:
32 | float x, y; // Ball's position
33 | float vx, vy; // Ball's velocity
34 | float gravity; // Gravity effect
35 | float elasticity; // Bounce reduction factor
36 | int ballRadius; // Ball radius
37 | int captureRadius; // Slightly larger to ensure clean edges
38 | int rotation = 0;
39 |
40 | uint16_t *backgroundBuffer; // Buffer for storing background
41 |
42 | public:
43 | BouncingBall()
44 | {
45 | ballRadius = 20;
46 | captureRadius = ballRadius + 4;
47 | x = ballRadius + 5;
48 | y = tft->height() / 2;
49 | vx = 10; // Initial horizontal velocity
50 | vy = 0; // Initial vertical velocity
51 | gravity = 0.8; // Adjust as needed
52 | elasticity = 1; // Adjust as needed (between 0 and 1)
53 | backgroundBuffer = new uint16_t[(captureRadius * 2) * (captureRadius * 2)]; // Allocate memory for background buffer
54 | }
55 |
56 | ~BouncingBall()
57 | {
58 | if (backgroundBuffer)
59 | {
60 | delete[] backgroundBuffer; // Free memory when done
61 | }
62 | }
63 |
64 | void update()
65 | {
66 | // Logic to update ball position and handle collisions
67 | vy += gravity;
68 | x += vx;
69 | y += vy;
70 |
71 | if (x <= ballRadius || x >= tft->width() - ballRadius)
72 | {
73 | vx = -vx;
74 | x += vx;
75 | }
76 |
77 | if (y <= ballRadius || y >= tft->height() - ballRadius)
78 | {
79 | vy = -vy * elasticity;
80 | y += vy;
81 | }
82 | rotation += vx / 3.0; // Adjust rotation speed based on velocity
83 | }
84 |
85 | void init()
86 | {
87 | tft->readRect(x - captureRadius, y - captureRadius, captureRadius * 2, captureRadius * 2, backgroundBuffer);
88 | }
89 |
90 | void draw()
91 | {
92 |
93 | // Erase the ball at the current position by restoring the background
94 | tft->pushImage(x - captureRadius, y - captureRadius, captureRadius * 2, captureRadius * 2, backgroundBuffer);
95 |
96 | // Update position for the next frame
97 | update();
98 |
99 | // Capture the background at the new position, slightly larger area
100 | tft->readRect(x - captureRadius, y - captureRadius, captureRadius * 2, captureRadius * 2, backgroundBuffer);
101 |
102 | // Draw the ball at the new position
103 | tft->fillCircle(x, y, ballRadius, 0xf5e5);
104 | }
105 | };
106 |
107 | void runBouncingBall()
108 | {
109 | BouncingBall ball;
110 |
111 | tft->fillScreen(TFT_BLACK);
112 | tft->drawRGBBitmap(0, 0, (uint16_t *)ballcourt, ballcourt_width, ballcourt_height);
113 | ball.init();
114 | while (true)
115 | {
116 | ball.draw();
117 | tft->output(); // Update the virtual display
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/examples/4x1Screens/font_test/font_test.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 |
6 | #include "virtualScreen.h"
7 | #include "Starjedi32pt7b.h"
8 | #include "raidercrusader48pt7b.h"
9 | #include "Star_Trek_Enterprise_Future80pt7b.h"
10 |
11 | VirtualDisplay *tft;
12 |
13 | void setup()
14 | {
15 | Serial.begin(115200);
16 |
17 | ScreenBuilder screens;
18 |
19 | // 4 sreens on one row
20 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
21 |
22 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
23 | tft->begin();
24 |
25 |
26 | tft->fillScreen(TFT_BLACK);
27 | tft->drawRect(10, 20, tft->width() - 50, tft->height() - 50, TFT_GREEN);
28 | tft->drawRect(12, 23, tft->width() - 48, tft->height() - 48, TFT_GREEN);
29 | tft->drawRoundRect(20, 50, tft->width() - 80, tft->height() - 100, 20, TFT_CYAN);
30 | printCenteredText(tft, "Star Wars Yoda Jedi", &Starjedi32pt7b, 0x00ff0c);
31 | tft->output();
32 | delay(5000);
33 | tft->fillScreen(TFT_BLACK);
34 | printCenteredText(tft, "We are Crusaders!", &raidercrusader48pt7b, 0x17bb);
35 | tft->output();
36 | delay(5000);
37 | tft->fillScreen(TFT_BLACK);
38 | printCenteredText(tft, "Star Trek Kirk", &Star_Trek_Enterprise_Future80pt7b, 0x3728);
39 | tft->output();
40 | }
41 |
42 | void loop()
43 | {
44 | }
45 |
46 | void printCenteredText(VirtualDisplay *tft, const String &text, const GFXfont *font, uint16_t color)
47 | {
48 |
49 | tft->setFont(font);
50 | tft->setTextColor(color);
51 |
52 | int16_t x1, y1;
53 | uint16_t w, h;
54 | tft->getTextBounds(text, 0, 0, &x1, &y1, &w, &h); // Calculate the bounds of the text
55 |
56 | int x = (tft->width() - w) / 2; // Calculate the x position to center the text
57 | int y = (tft->height() + h) / 2; // Center vertically
58 |
59 | tft->setCursor(x, y);
60 | tft->println(text);
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/examples/4x1Screens/gameoflife/BebasNeue_Regular13pt7b.h:
--------------------------------------------------------------------------------
1 | const uint8_t BebasNeue_Regular13pt7bBitmaps[] PROGMEM = {
2 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x07, 0xFC, 0xEF, 0xDB, 0xB6, 0x6C,
3 | 0xC9, 0x80, 0x19, 0x86, 0x61, 0x98, 0x66, 0x7F, 0xDF, 0xF3, 0xB8, 0xCC,
4 | 0x33, 0x0C, 0xC7, 0xF9, 0xFE, 0xFF, 0x8C, 0xC7, 0x71, 0xDC, 0x67, 0x19,
5 | 0x80, 0x18, 0x18, 0x7E, 0xFF, 0xE7, 0xE3, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
6 | 0x0F, 0x07, 0xE7, 0xE7, 0xE7, 0xFF, 0x7E, 0x18, 0x18, 0x70, 0x67, 0xC6,
7 | 0x36, 0x31, 0xB1, 0x8D, 0x98, 0x6C, 0xC3, 0x64, 0x1B, 0x60, 0xFB, 0x73,
8 | 0xB7, 0xC1, 0xB6, 0x09, 0x30, 0xC9, 0x86, 0x4C, 0x62, 0x63, 0x1B, 0x18,
9 | 0xF9, 0x83, 0x80, 0x3E, 0x3F, 0x3F, 0x9C, 0x0E, 0x07, 0x1B, 0x8C, 0xFF,
10 | 0x3F, 0xBF, 0xF8, 0xDC, 0x6E, 0x37, 0x1B, 0x9D, 0xFE, 0xFF, 0x3D, 0xC0,
11 | 0xFF, 0xEC, 0x80, 0x1B, 0xDF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73,
12 | 0x9C, 0xE7, 0x3E, 0xF3, 0x80, 0x87, 0xBC, 0x73, 0x9C, 0xE7, 0x39, 0xCE,
13 | 0x73, 0x9C, 0xE7, 0x39, 0xFF, 0xEE, 0x00, 0x0E, 0x03, 0x04, 0x45, 0xD7,
14 | 0xFF, 0xC3, 0x81, 0xB0, 0xEE, 0x31, 0x80, 0x18, 0x0C, 0x06, 0x1F, 0xFF,
15 | 0xFF, 0xFC, 0x60, 0x30, 0x18, 0x00, 0xFF, 0xAD, 0x80, 0xFF, 0xFE, 0xFF,
16 | 0x80, 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x07, 0x01, 0xC0, 0x60, 0x38, 0x0C,
17 | 0x03, 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x03, 0x01, 0xC0, 0x60, 0x38, 0x00,
18 | 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
19 | 0xE3, 0xE3, 0xE7, 0xFF, 0x7F, 0x3C, 0x0C, 0x7F, 0xFF, 0xFC, 0x71, 0xC7,
20 | 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x70, 0x3C, 0x7F, 0xFF, 0xE7,
21 | 0xE3, 0xE7, 0x07, 0x07, 0x0E, 0x1C, 0x3C, 0x78, 0x70, 0xE0, 0xE0, 0xFF,
22 | 0xFF, 0xFF, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7, 0x07, 0x07, 0x1F, 0x1C, 0x1E,
23 | 0x07, 0x07, 0xC7, 0xC7, 0xE7, 0xFF, 0x7E, 0x3C, 0x07, 0x81, 0xE0, 0xF8,
24 | 0x3E, 0x0F, 0x87, 0xE1, 0xB8, 0xEE, 0x33, 0x9C, 0xE7, 0x39, 0x8E, 0xFF,
25 | 0xFF, 0xFF, 0xFC, 0x0E, 0x03, 0x80, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0,
26 | 0xE4, 0xFF, 0xFF, 0xE7, 0xE7, 0x03, 0x03, 0xE3, 0xE3, 0xE7, 0xFF, 0x7F,
27 | 0x3C, 0x3C, 0x7F, 0xFF, 0xE3, 0xE3, 0xE0, 0xE4, 0xFF, 0xFF, 0xE7, 0xE3,
28 | 0xE3, 0xE3, 0xE3, 0xE3, 0xFF, 0x7F, 0x3E, 0xFF, 0xFF, 0xFF, 0x07, 0x07,
29 | 0x06, 0x0E, 0x0E, 0x0E, 0x1C, 0x1C, 0x1C, 0x18, 0x38, 0x38, 0x38, 0x70,
30 | 0x70, 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E, 0xFF, 0xE7,
31 | 0xE3, 0xE3, 0xE3, 0xE3, 0xFF, 0xFF, 0x3E, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7,
32 | 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, 0x7F, 0x27, 0x07, 0xC7, 0xE7, 0xFF, 0x7E,
33 | 0x3C, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0xB4,
34 | 0x03, 0x0F, 0x3C, 0xF0, 0xE0, 0x7C, 0x1F, 0x03, 0xFF, 0xFF, 0xFF, 0x00,
35 | 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3E, 0x0F, 0x07, 0x3E, 0xF8, 0xC0, 0x3E,
36 | 0x3F, 0x9F, 0xCC, 0x7E, 0x3F, 0x1C, 0x0C, 0x0E, 0x0E, 0x07, 0x07, 0x03,
37 | 0x81, 0x80, 0x00, 0x00, 0x38, 0x1C, 0x0E, 0x00, 0x00, 0x40, 0x07, 0xF8,
38 | 0x1F, 0xFC, 0x3C, 0x1E, 0x38, 0x07, 0x71, 0x37, 0x67, 0xB3, 0xE7, 0xF3,
39 | 0xC6, 0x73, 0xCE, 0x73, 0xCE, 0x73, 0xCE, 0x73, 0xCE, 0x76, 0xCE, 0xFE,
40 | 0xCF, 0xFC, 0xE7, 0x78, 0xE0, 0x00, 0x70, 0x08, 0x3F, 0xF8, 0x1F, 0xF8,
41 | 0x07, 0xE0, 0x1E, 0x07, 0x81, 0xE0, 0x7C, 0x3F, 0x0F, 0xC3, 0xF0, 0xCC,
42 | 0x33, 0x0C, 0xE7, 0x39, 0xCE, 0x7F, 0x9F, 0xE6, 0x19, 0x87, 0x61, 0xF8,
43 | 0x70, 0xFE, 0x7F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x9D, 0xFE, 0xFE, 0x7F,
44 | 0xB9, 0xDC, 0x7E, 0x3F, 0x1F, 0x8F, 0xFE, 0xFF, 0x7F, 0x00, 0x3C, 0x7E,
45 | 0xFF, 0xE7, 0xE7, 0xE7, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7,
46 | 0xE7, 0xFF, 0x7E, 0x3C, 0xFE, 0x7F, 0xBF, 0xDC, 0x6E, 0x3F, 0x1F, 0x8F,
47 | 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8D, 0xFE, 0xFF, 0x7F,
48 | 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0,
49 | 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x1C,
50 | 0x38, 0x7E, 0xFD, 0xFB, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x3C,
51 | 0x7E, 0xFF, 0xE7, 0xE3, 0xE3, 0xE0, 0xE0, 0xEF, 0xEF, 0xEF, 0xE3, 0xE3,
52 | 0xE3, 0xE7, 0xFF, 0x7E, 0x3C, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F,
53 | 0x8F, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3,
54 | 0xF1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1C, 0x71, 0xC7,
55 | 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xFF, 0xFB, 0xC0, 0xE3,
56 | 0xF1, 0xB9, 0xDC, 0xCE, 0xE7, 0x73, 0xF1, 0xF8, 0xFC, 0x7F, 0x3F, 0x9D,
57 | 0xCE, 0x77, 0x3B, 0x9D, 0xC7, 0xE3, 0xF1, 0xC0, 0xE1, 0xC3, 0x87, 0x0E,
58 | 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x7F, 0xFF, 0xFC,
59 | 0xF0, 0xFF, 0x1F, 0xF1, 0xFF, 0x9F, 0xF9, 0xFD, 0x9F, 0xD9, 0xFD, 0x9F,
60 | 0xDB, 0x7D, 0xB7, 0xDB, 0x7C, 0xF7, 0xCF, 0x7C, 0xF7, 0xCE, 0x7C, 0xE7,
61 | 0xCE, 0x7C, 0xE7, 0xF3, 0xF9, 0xFC, 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7,
62 | 0xFF, 0xF7, 0xFB, 0xFD, 0xFE, 0x7F, 0x3F, 0x9F, 0xCF, 0xE3, 0xF1, 0xC0,
63 | 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
64 | 0xE3, 0xE3, 0xE7, 0xFF, 0x7F, 0x3C, 0xFC, 0xFF, 0xFF, 0xE7, 0xE3, 0xE3,
65 | 0xE3, 0xE7, 0xFF, 0xFE, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
66 | 0x3C, 0x3F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0xB8,
67 | 0xDC, 0x6E, 0x37, 0x1B, 0x9D, 0xFE, 0x7F, 0x1F, 0xC0, 0xE0, 0x10, 0xFE,
68 | 0x7F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x8D, 0xCE, 0xFE, 0x7F, 0x3F, 0xDC,
69 | 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0x80, 0x3C, 0xFE, 0xFF, 0xC7,
70 | 0xC7, 0xE0, 0xE0, 0x70, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0xC7, 0xFF,
71 | 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0xE3, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C,
72 | 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x00, 0xE3,
73 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
74 | 0xE3, 0xE7, 0xFF, 0x7E, 0x3C, 0xE1, 0xB0, 0xD8, 0xEE, 0x77, 0x3B, 0x9D,
75 | 0xCC, 0xE6, 0x33, 0x19, 0x8F, 0xC7, 0xE3, 0xF1, 0xF0, 0xF8, 0x3C, 0x1E,
76 | 0x0F, 0x00, 0xE3, 0x9D, 0x8E, 0x76, 0x79, 0xD9, 0xE6, 0x67, 0x99, 0xDE,
77 | 0x67, 0x79, 0x9D, 0xE6, 0x76, 0xD9, 0xDB, 0x67, 0x6F, 0x8D, 0xBE, 0x3E,
78 | 0xF8, 0xF3, 0xC3, 0xCF, 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC0, 0xF1, 0xDC,
79 | 0x67, 0x38, 0xCE, 0x3B, 0x0F, 0xC1, 0xF0, 0x78, 0x1E, 0x07, 0x81, 0xE0,
80 | 0x7C, 0x3F, 0x0C, 0xC7, 0x39, 0xCE, 0x61, 0xF8, 0x70, 0xE1, 0xDC, 0x67,
81 | 0x39, 0xCE, 0x33, 0x0E, 0xC3, 0xF0, 0x78, 0x1E, 0x07, 0x80, 0xC0, 0x30,
82 | 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x7F, 0xBF, 0xDF, 0xE0,
83 | 0xE0, 0x70, 0x70, 0x38, 0x1C, 0x1C, 0x0E, 0x0E, 0x07, 0x03, 0x83, 0x81,
84 | 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39,
85 | 0xCE, 0x73, 0x9C, 0xE7, 0x3F, 0xFF, 0x80, 0xE0, 0x18, 0x07, 0x00, 0xC0,
86 | 0x30, 0x0E, 0x01, 0x80, 0x70, 0x0C, 0x03, 0x00, 0xE0, 0x18, 0x07, 0x00,
87 | 0xC0, 0x30, 0x0E, 0x01, 0x80, 0x70, 0xFF, 0xFE, 0x73, 0x9C, 0xE7, 0x39,
88 | 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xFF, 0xFF, 0x80, 0x0C, 0x07, 0x81, 0xE0,
89 | 0xEC, 0x33, 0x1C, 0x6E, 0x1C, 0xFF, 0xFF, 0xFF, 0xE3, 0x8E, 0x1E, 0x07,
90 | 0x81, 0xE0, 0x7C, 0x3F, 0x0F, 0xC3, 0xF0, 0xCC, 0x33, 0x0C, 0xE7, 0x39,
91 | 0xCE, 0x7F, 0x9F, 0xE6, 0x19, 0x87, 0x61, 0xF8, 0x70, 0xFE, 0x7F, 0xBF,
92 | 0xDC, 0xEE, 0x37, 0x1B, 0x9D, 0xFE, 0xFE, 0x7F, 0xB9, 0xDC, 0x7E, 0x3F,
93 | 0x1F, 0x8F, 0xFE, 0xFF, 0x7F, 0x00, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7, 0xE7,
94 | 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, 0x7E, 0x3C,
95 | 0xFE, 0x7F, 0xBF, 0xDC, 0x6E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF8,
96 | 0xFC, 0x7E, 0x3F, 0x1F, 0x8D, 0xFE, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF,
97 | 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
98 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x1C, 0x38, 0x7E, 0xFD, 0xFB,
99 | 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x3C, 0x7E, 0xFF, 0xE7, 0xE3,
100 | 0xE3, 0xE0, 0xE0, 0xEF, 0xEF, 0xEF, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E,
101 | 0x3C, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xFF, 0xFF, 0xFF,
102 | 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xC0, 0xFF, 0xFF,
103 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
104 | 0x71, 0xC7, 0x1C, 0x71, 0xFF, 0xFB, 0xC0, 0xE3, 0xF1, 0xB9, 0xDC, 0xCE,
105 | 0xE7, 0x73, 0xF1, 0xF8, 0xFC, 0x7F, 0x3F, 0x9D, 0xCE, 0x77, 0x3B, 0x9D,
106 | 0xC7, 0xE3, 0xF1, 0xC0, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1,
107 | 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x7F, 0xFF, 0xFC, 0xF0, 0xFF, 0x1F, 0xF1,
108 | 0xFF, 0x9F, 0xF9, 0xFD, 0x9F, 0xD9, 0xFD, 0x9F, 0xDB, 0x7D, 0xB7, 0xDB,
109 | 0x7C, 0xF7, 0xCF, 0x7C, 0xF7, 0xCE, 0x7C, 0xE7, 0xCE, 0x7C, 0xE7, 0xF3,
110 | 0xF9, 0xFC, 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFF, 0xF7, 0xFB, 0xFD,
111 | 0xFE, 0x7F, 0x3F, 0x9F, 0xCF, 0xE3, 0xF1, 0xC0, 0x3C, 0x7F, 0xFF, 0xE7,
112 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF,
113 | 0x7F, 0x3C, 0xFC, 0xFF, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0xFE,
114 | 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x3C, 0x3F, 0xBF, 0xDC,
115 | 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0xB8, 0xDC, 0x6E, 0x37, 0x1B,
116 | 0x9D, 0xFE, 0x7F, 0x1F, 0xC0, 0xE0, 0x10, 0xFE, 0x7F, 0xBF, 0xDC, 0xEE,
117 | 0x37, 0x1B, 0x8D, 0xCE, 0xFE, 0x7F, 0x3F, 0xDC, 0xEE, 0x37, 0x1B, 0x8D,
118 | 0xC6, 0xE3, 0x71, 0x80, 0x3C, 0xFE, 0xFF, 0xC7, 0xC7, 0xE0, 0xE0, 0x70,
119 | 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0xC7, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF,
120 | 0xFF, 0xE3, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81,
121 | 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x00, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
122 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E,
123 | 0x3C, 0xE1, 0xB0, 0xD8, 0xEE, 0x77, 0x3B, 0x9D, 0xCC, 0xE6, 0x33, 0x19,
124 | 0x8F, 0xC7, 0xE3, 0xF1, 0xF0, 0xF8, 0x3C, 0x1E, 0x0F, 0x00, 0xE3, 0x9D,
125 | 0x8E, 0x76, 0x79, 0xD9, 0xE6, 0x67, 0x99, 0xDE, 0x67, 0x79, 0x9D, 0xE6,
126 | 0x76, 0xD9, 0xDB, 0x67, 0x6F, 0x8D, 0xBE, 0x3E, 0xF8, 0xF3, 0xC3, 0xCF,
127 | 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC0, 0xF1, 0xDC, 0x67, 0x38, 0xCE, 0x3B,
128 | 0x0F, 0xC1, 0xF0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x7C, 0x3F, 0x0C, 0xC7,
129 | 0x39, 0xCE, 0x61, 0xF8, 0x70, 0xE1, 0xDC, 0x67, 0x39, 0xCE, 0x33, 0x0E,
130 | 0xC3, 0xF0, 0x78, 0x1E, 0x07, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
131 | 0x30, 0x0C, 0x03, 0x00, 0x7F, 0xBF, 0xDF, 0xE0, 0xE0, 0x70, 0x70, 0x38,
132 | 0x1C, 0x1C, 0x0E, 0x0E, 0x07, 0x03, 0x83, 0x81, 0xC1, 0xFF, 0xFF, 0xFF,
133 | 0xC0, 0x19, 0xDE, 0xE7, 0x39, 0xCE, 0x77, 0x39, 0xC7, 0x39, 0xCE, 0x73,
134 | 0x9E, 0xF3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
135 | 0xE0, 0x87, 0x3C, 0xE7, 0x39, 0xCE, 0x71, 0xCE, 0x77, 0x39, 0xCE, 0x73,
136 | 0xBD, 0xEE, 0x00, 0x10, 0x9F, 0xFF, 0xF9, 0x1C };
137 |
138 | const GFXglyph BebasNeue_Regular13pt7bGlyphs[] PROGMEM = {
139 | { 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
140 | { 1, 3, 18, 5, 1, -17 }, // 0x21 '!'
141 | { 8, 7, 6, 9, 1, -17 }, // 0x22 '"'
142 | { 14, 10, 18, 10, 0, -17 }, // 0x23 '#'
143 | { 37, 8, 20, 10, 1, -18 }, // 0x24 '$'
144 | { 57, 13, 18, 15, 1, -17 }, // 0x25 '%'
145 | { 87, 9, 18, 11, 1, -17 }, // 0x26 '&'
146 | { 108, 3, 6, 5, 1, -17 }, // 0x27 '''
147 | { 111, 5, 21, 7, 1, -19 }, // 0x28 '('
148 | { 125, 5, 21, 7, 1, -19 }, // 0x29 ')'
149 | { 139, 10, 9, 11, 0, -17 }, // 0x2A '*'
150 | { 151, 9, 9, 10, 1, -12 }, // 0x2B '+'
151 | { 162, 3, 6, 5, 1, -2 }, // 0x2C ','
152 | { 165, 5, 3, 7, 1, -10 }, // 0x2D '-'
153 | { 167, 3, 3, 5, 1, -2 }, // 0x2E '.'
154 | { 169, 10, 18, 10, 0, -17 }, // 0x2F '/'
155 | { 192, 8, 18, 10, 1, -17 }, // 0x30 '0'
156 | { 210, 6, 18, 10, 2, -17 }, // 0x31 '1'
157 | { 224, 8, 18, 10, 1, -17 }, // 0x32 '2'
158 | { 242, 8, 18, 10, 1, -17 }, // 0x33 '3'
159 | { 260, 10, 18, 10, 0, -17 }, // 0x34 '4'
160 | { 283, 8, 18, 10, 1, -17 }, // 0x35 '5'
161 | { 301, 8, 18, 10, 1, -17 }, // 0x36 '6'
162 | { 319, 8, 18, 10, 1, -17 }, // 0x37 '7'
163 | { 337, 8, 18, 10, 1, -17 }, // 0x38 '8'
164 | { 355, 8, 18, 10, 1, -17 }, // 0x39 '9'
165 | { 373, 3, 13, 5, 1, -12 }, // 0x3A ':'
166 | { 378, 3, 16, 5, 1, -12 }, // 0x3B ';'
167 | { 384, 8, 8, 10, 1, -12 }, // 0x3C '<'
168 | { 392, 8, 7, 10, 1, -12 }, // 0x3D '='
169 | { 399, 8, 8, 10, 1, -12 }, // 0x3E '>'
170 | { 407, 9, 18, 9, 0, -17 }, // 0x3F '?'
171 | { 428, 16, 21, 18, 1, -18 }, // 0x40 '@'
172 | { 470, 10, 18, 10, 0, -17 }, // 0x41 'A'
173 | { 493, 9, 18, 10, 1, -17 }, // 0x42 'B'
174 | { 514, 8, 18, 10, 1, -17 }, // 0x43 'C'
175 | { 532, 9, 18, 10, 1, -17 }, // 0x44 'D'
176 | { 553, 8, 18, 9, 1, -17 }, // 0x45 'E'
177 | { 571, 7, 18, 9, 1, -17 }, // 0x46 'F'
178 | { 587, 8, 18, 10, 1, -17 }, // 0x47 'G'
179 | { 605, 9, 18, 11, 1, -17 }, // 0x48 'H'
180 | { 626, 3, 18, 5, 1, -17 }, // 0x49 'I'
181 | { 633, 6, 18, 7, 0, -17 }, // 0x4A 'J'
182 | { 647, 9, 18, 11, 1, -17 }, // 0x4B 'K'
183 | { 668, 7, 18, 9, 1, -17 }, // 0x4C 'L'
184 | { 684, 12, 18, 14, 1, -17 }, // 0x4D 'M'
185 | { 711, 9, 18, 11, 1, -17 }, // 0x4E 'N'
186 | { 732, 8, 18, 10, 1, -17 }, // 0x4F 'O'
187 | { 750, 8, 18, 10, 1, -17 }, // 0x50 'P'
188 | { 768, 9, 20, 10, 1, -17 }, // 0x51 'Q'
189 | { 791, 9, 18, 10, 1, -17 }, // 0x52 'R'
190 | { 812, 8, 18, 9, 1, -17 }, // 0x53 'S'
191 | { 830, 9, 18, 9, 0, -17 }, // 0x54 'T'
192 | { 851, 8, 18, 10, 1, -17 }, // 0x55 'U'
193 | { 869, 9, 18, 10, 0, -17 }, // 0x56 'V'
194 | { 890, 14, 18, 14, 0, -17 }, // 0x57 'W'
195 | { 922, 10, 18, 10, 0, -17 }, // 0x58 'X'
196 | { 945, 10, 18, 10, 0, -17 }, // 0x59 'Y'
197 | { 968, 9, 18, 9, 0, -17 }, // 0x5A 'Z'
198 | { 989, 5, 21, 7, 1, -19 }, // 0x5B '['
199 | { 1003, 10, 18, 10, 0, -17 }, // 0x5C '\'
200 | { 1026, 5, 21, 7, 1, -19 }, // 0x5D ']'
201 | { 1040, 10, 7, 10, 0, -17 }, // 0x5E '^'
202 | { 1049, 8, 3, 8, 0, 0 }, // 0x5F '_'
203 | { 1052, 5, 3, 13, 3, -21 }, // 0x60 '`'
204 | { 1054, 10, 18, 10, 0, -17 }, // 0x61 'a'
205 | { 1077, 9, 18, 10, 1, -17 }, // 0x62 'b'
206 | { 1098, 8, 18, 10, 1, -17 }, // 0x63 'c'
207 | { 1116, 9, 18, 10, 1, -17 }, // 0x64 'd'
208 | { 1137, 8, 18, 9, 1, -17 }, // 0x65 'e'
209 | { 1155, 7, 18, 9, 1, -17 }, // 0x66 'f'
210 | { 1171, 8, 18, 10, 1, -17 }, // 0x67 'g'
211 | { 1189, 9, 18, 11, 1, -17 }, // 0x68 'h'
212 | { 1210, 3, 18, 5, 1, -17 }, // 0x69 'i'
213 | { 1217, 6, 18, 7, 0, -17 }, // 0x6A 'j'
214 | { 1231, 9, 18, 11, 1, -17 }, // 0x6B 'k'
215 | { 1252, 7, 18, 9, 1, -17 }, // 0x6C 'l'
216 | { 1268, 12, 18, 14, 1, -17 }, // 0x6D 'm'
217 | { 1295, 9, 18, 11, 1, -17 }, // 0x6E 'n'
218 | { 1316, 8, 18, 10, 1, -17 }, // 0x6F 'o'
219 | { 1334, 8, 18, 10, 1, -17 }, // 0x70 'p'
220 | { 1352, 9, 20, 10, 1, -17 }, // 0x71 'q'
221 | { 1375, 9, 18, 10, 1, -17 }, // 0x72 'r'
222 | { 1396, 8, 18, 9, 1, -17 }, // 0x73 's'
223 | { 1414, 9, 18, 9, 0, -17 }, // 0x74 't'
224 | { 1435, 8, 18, 10, 1, -17 }, // 0x75 'u'
225 | { 1453, 9, 18, 10, 0, -17 }, // 0x76 'v'
226 | { 1474, 14, 18, 14, 0, -17 }, // 0x77 'w'
227 | { 1506, 10, 18, 10, 0, -17 }, // 0x78 'x'
228 | { 1529, 10, 18, 10, 0, -17 }, // 0x79 'y'
229 | { 1552, 9, 18, 9, 0, -17 }, // 0x7A 'z'
230 | { 1573, 5, 21, 7, 1, -19 }, // 0x7B '{'
231 | { 1587, 3, 25, 13, 5, -19 }, // 0x7C '|'
232 | { 1597, 5, 21, 7, 1, -19 }, // 0x7D '}'
233 | { 1611, 10, 4, 10, 0, -10 } }; // 0x7E '~'
234 |
235 | const GFXfont BebasNeue_Regular13pt7b PROGMEM = {
236 | (uint8_t *)BebasNeue_Regular13pt7bBitmaps,
237 | (GFXglyph *)BebasNeue_Regular13pt7bGlyphs,
238 | 0x20, 0x7E, 31 };
239 |
240 | // Approx. 2288 bytes
241 |
--------------------------------------------------------------------------------
/examples/4x1Screens/gameoflife/gameoflife.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "BebasNeue_Regular13pt7b.h"
7 |
8 | VirtualDisplay *tft;
9 | ScreenBuilder screens;
10 |
11 | void setup()
12 | {
13 | Serial.begin(115200);
14 |
15 | // Adjust this setup according to your actual screen layout
16 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
17 |
18 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
19 | tft->begin();
20 |
21 |
22 | gameOfLife();
23 | }
24 |
25 | void loop()
26 | {
27 | }
28 |
29 | int gridWidth; // Width of the grid
30 | int gridHeight; // Height of the grid
31 | bool **currentGrid;
32 | bool **nextGrid;
33 | const int squareSize = 10;
34 | const int statsWidth = 240; // Width of the stats area on the left, adjust as needed
35 | int aliveCellsCount = 0;
36 | int changeRate = 0;
37 | const uint16_t statsBgColor = 0x3186;
38 | std::vector populationHistory;
39 |
40 | void gameOfLife()
41 | {
42 | tft->fillScreen(TFT_BLACK);
43 | setupGameOfLife(); // Initialize the game
44 | for (int i = 0; i < 1000; i++)
45 | { // Run for 1000 generations
46 | updateGameOfLife(); // Update the grid
47 | drawGameOfLife(); // Draw the grid
48 | drawStats(i); // Draw the stats with the current generation
49 | drawPopulationGraph();
50 |
51 | delay(100); // Delay between generations
52 | }
53 | cleanupGameOfLife(); // Clean up the dynamically allocated memory
54 | }
55 |
56 | void setupGameOfLife()
57 | {
58 | gridWidth = (tft->width() - statsWidth) / squareSize; // Adjusted for stats area
59 | gridHeight = tft->height() / squareSize;
60 |
61 | // Allocate memory for the grids
62 | currentGrid = new bool *[gridHeight];
63 | nextGrid = new bool *[gridHeight];
64 | for (int y = 0; y < gridHeight; y++)
65 | {
66 | currentGrid[y] = new bool[gridWidth];
67 | nextGrid[y] = new bool[gridWidth];
68 | }
69 |
70 | // Randomly initialize the currentGrid
71 | for (int y = 0; y < gridHeight; y++)
72 | {
73 | for (int x = 0; x < gridWidth; x++)
74 | {
75 | currentGrid[y][x] = esp_random() % 2; // Randomly alive or dead
76 | }
77 | }
78 | }
79 |
80 | void cleanupGameOfLife()
81 | {
82 | for (int y = 0; y < gridHeight; y++)
83 | {
84 | delete[] currentGrid[y];
85 | delete[] nextGrid[y];
86 | }
87 | delete[] currentGrid;
88 | delete[] nextGrid;
89 | }
90 |
91 | void updateGameOfLife()
92 | {
93 | int newAliveCellsCount = 0;
94 | int newChangeRate = 0;
95 |
96 | // Apply Game of Life rules to update the grid
97 | for (int y = 0; y < gridHeight; y++)
98 | {
99 | for (int x = 0; x < gridWidth; x++)
100 | {
101 | int aliveNeighbors = 0;
102 |
103 | // Count alive neighbors
104 | for (int i = -1; i <= 1; i++)
105 | {
106 | for (int j = -1; j <= 1; j++)
107 | {
108 | if (i == 0 && j == 0)
109 | {
110 | continue; // Skip the current cell
111 | }
112 | int nx = x + j;
113 | int ny = y + i;
114 | if (nx >= 0 && nx < gridWidth && ny >= 0 && ny < gridHeight && currentGrid[ny][nx])
115 | {
116 | aliveNeighbors++;
117 | }
118 | }
119 | }
120 |
121 | // Apply the rules of the Game of Life
122 | bool newState = currentGrid[y][x];
123 | if (currentGrid[y][x] && (aliveNeighbors < 2 || aliveNeighbors > 3))
124 | {
125 | newState = false; // Cell dies
126 | }
127 | else if (!currentGrid[y][x] && aliveNeighbors == 3)
128 | {
129 | newState = true; // Cell becomes alive
130 | }
131 |
132 | if (newState != currentGrid[y][x])
133 | {
134 | newChangeRate++; // Increment change rate if cell state changes
135 | }
136 |
137 | if (newState)
138 | {
139 | newAliveCellsCount++; // Count alive cells
140 | }
141 |
142 | nextGrid[y][x] = newState;
143 | }
144 | }
145 |
146 | // Copy nextGrid to currentGrid for the next iteration and update stats
147 | for (int y = 0; y < gridHeight; y++)
148 | {
149 | for (int x = 0; x < gridWidth; x++)
150 | {
151 | currentGrid[y][x] = nextGrid[y][x];
152 | }
153 | }
154 |
155 | aliveCellsCount = newAliveCellsCount;
156 | populationHistory.push_back(newAliveCellsCount);
157 | changeRate = newChangeRate;
158 | }
159 |
160 | void drawGameOfLife()
161 | {
162 | for (int y = 0; y < gridHeight; y++)
163 | {
164 | for (int x = 0; x < gridWidth; x++)
165 | {
166 | uint16_t color = currentGrid[y][x] ? 0x07e0 : TFT_BLACK;
167 | tft->fillRect(x * squareSize + statsWidth, y * squareSize, squareSize, squareSize, color);
168 | }
169 | }
170 | tft->output();
171 | }
172 | void drawPopulationGraph()
173 | {
174 | int graphWidth = statsWidth - 10; // Width of the graph, leaving some margin
175 | int graphHeight = 50; // Height of the graph, adjust as needed
176 | int graphX = 5; // X position of the graph
177 | int graphY = tft->height() - graphHeight - 10; // Y position, placed at the bottom
178 | int titleHeight = 15; // Height for the title area
179 |
180 | // Clear the area for the graph and title
181 | tft->fillRect(graphX, graphY - titleHeight, graphWidth, graphHeight + titleHeight, statsBgColor);
182 |
183 | // Draw the title for the graph
184 | tft->setTextColor(0x07fb);
185 | tft->setCursor(8, graphY - titleHeight); // Set position for the title
186 | tft->print("Population Over Time");
187 |
188 | // Check if there is enough data to draw the graph
189 | if (populationHistory.size() < 2)
190 | return;
191 |
192 | // Calculate the scaling factor for the graph
193 | int maxPopulation = *std::max_element(populationHistory.begin(), populationHistory.end());
194 | float scaleY = static_cast(graphHeight) / maxPopulation;
195 | float scaleX = static_cast(graphWidth) / (populationHistory.size() - 1);
196 |
197 | // Draw the graph line
198 | for (size_t i = 0; i < populationHistory.size() - 1; ++i)
199 | {
200 | int x0 = graphX + i * scaleX;
201 | int y0 = graphY + graphHeight - populationHistory[i] * scaleY;
202 | int x1 = graphX + (i + 1) * scaleX;
203 | int y1 = graphY + graphHeight - populationHistory[i + 1] * scaleY;
204 | tft->drawLine(x0, y0, x1, y1, TFT_YELLOW);
205 | }
206 | }
207 |
208 | void drawStats(int generation)
209 | {
210 | // Clear the stats area
211 | tft->fillRect(0, 0, statsWidth, tft->height(), statsBgColor);
212 |
213 | tft->setTextColor(0x07fb);
214 | tft->setFont(&BebasNeue_Regular13pt7b);
215 | tft->setCursor(8, 30);
216 | tft->print("Generation:");
217 | tft->setTextColor(TFT_WHITE);
218 | tft->print(generation);
219 | tft->setTextColor(0x07fb);
220 | tft->setCursor(8, 60);
221 | tft->print("Alive: ");
222 | tft->setTextColor(TFT_WHITE);
223 | tft->print(aliveCellsCount);
224 | tft->setCursor(8, 90);
225 | tft->setTextColor(0x07fb);
226 | tft->print("Change: ");
227 | tft->setTextColor(TFT_WHITE);
228 | tft->print(changeRate);
229 | }
230 |
--------------------------------------------------------------------------------
/examples/4x1Screens/image/image.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "night_earth_960x240.h"
7 | #include "newyork_960x240.h"
8 |
9 |
10 | VirtualDisplay *tft;
11 | ScreenBuilder screens;
12 |
13 | void setup()
14 | {
15 | Serial.begin(115200);
16 |
17 | // Adjust this setup according to your actual screen layout
18 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
19 |
20 |
21 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
22 | tft->begin();
23 |
24 | tft->fillScreen(TFT_BLACK);
25 | tft->drawRGBBitmap(0, 0, (uint16_t *)night_earth, night_earth_width, night_earth_height);
26 | tft->output();
27 | delay(5000);
28 | tft->fillScreen(TFT_BLACK);
29 | tft->drawRGBBitmap(0, 0, (uint16_t *)newyork, newyork_width, newyork_height);
30 | tft->output();
31 | }
32 |
33 |
34 | void loop()
35 | {
36 | }
37 |
--------------------------------------------------------------------------------
/examples/4x1Screens/maze/maze.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include
7 | #include
8 | #include // For std::pair
9 |
10 | VirtualDisplay *tft;
11 | ScreenBuilder screens;
12 |
13 | void setup()
14 | {
15 | Serial.begin(115200);
16 |
17 | // Adjust this setup according to your actual screen layout
18 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
19 |
20 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
21 | tft->begin();
22 |
23 | playMaze();
24 | }
25 |
26 | void loop()
27 | {
28 | }
29 |
30 | struct Cell
31 | {
32 | bool visited = false;
33 | bool topWall = true;
34 | bool bottomWall = true;
35 | bool leftWall = true;
36 | bool rightWall = true;
37 | };
38 |
39 | const int cellSize = 30; // Global cell size in pixels
40 | const int paddingSize = 5; // Total padding in pixels, adjust as needed
41 |
42 | std::vector> maze;
43 | int mazeWidth; // Maze width in cells
44 | int mazeHeight; // Maze height in cells
45 |
46 | void playMaze()
47 | {
48 | tft->fillScreen(TFT_BLACK);
49 | setupMaze();
50 | }
51 |
52 | std::vector> solveMaze()
53 | {
54 | std::stack> stack;
55 | std::vector> visited(mazeHeight, std::vector(mazeWidth, false));
56 | std::vector> path;
57 |
58 | // Start from an edge, for example, (0, 0)
59 | stack.push({0, 0});
60 | visited[0][0] = true;
61 |
62 | while (!stack.empty())
63 | {
64 | auto [x, y] = stack.top();
65 | path.push_back({x, y}); // Add to path
66 |
67 | // Check if the center is reached
68 | if (x == mazeWidth / 2 && y == mazeHeight / 2)
69 | {
70 | return path; // Return the path to the center
71 | }
72 |
73 | // Find unvisited neighbors without walls in between
74 | std::vector> unvisitedNeighbors;
75 | if (x > 0 && !visited[y][x - 1] && !maze[y][x].leftWall)
76 | {
77 | unvisitedNeighbors.push_back({x - 1, y});
78 | }
79 | if (y > 0 && !visited[y - 1][x] && !maze[y][x].topWall)
80 | {
81 | unvisitedNeighbors.push_back({x, y - 1});
82 | }
83 | if (x < mazeWidth - 1 && !visited[y][x + 1] && !maze[y][x].rightWall)
84 | {
85 | unvisitedNeighbors.push_back({x + 1, y});
86 | }
87 | if (y < mazeHeight - 1 && !visited[y + 1][x] && !maze[y][x].bottomWall)
88 | {
89 | unvisitedNeighbors.push_back({x, y + 1});
90 | }
91 |
92 | if (!unvisitedNeighbors.empty())
93 | {
94 | auto [nextX, nextY] = unvisitedNeighbors.back();
95 | visited[nextY][nextX] = true;
96 | stack.push({nextX, nextY});
97 | }
98 | else
99 | {
100 | stack.pop();
101 | path.pop_back(); // Remove from path if it's a dead end
102 | }
103 | }
104 | return path; // In case the center can't be reached, return the attempted path
105 | }
106 |
107 | void generateMaze()
108 | {
109 | std::stack> stack;
110 |
111 | // Start from the center of the maze
112 | int centerX = mazeWidth / 2;
113 | int centerY = mazeHeight / 2;
114 | maze[centerY][centerX].visited = true;
115 | stack.push({centerX, centerY});
116 |
117 | while (!stack.empty())
118 | {
119 | auto [x, y] = stack.top();
120 | std::vector> unvisitedNeighbors;
121 |
122 | // Check unvisited neighbors
123 | if (x > 0 && !maze[y][x - 1].visited)
124 | {
125 | unvisitedNeighbors.push_back({x - 1, y});
126 | }
127 | if (y > 0 && !maze[y - 1][x].visited)
128 | {
129 | unvisitedNeighbors.push_back({x, y - 1});
130 | }
131 | if (x < mazeWidth - 1 && !maze[y][x + 1].visited)
132 | {
133 | unvisitedNeighbors.push_back({x + 1, y});
134 | }
135 | if (y < mazeHeight - 1 && !maze[y + 1][x].visited)
136 | {
137 | unvisitedNeighbors.push_back({x, y + 1});
138 | }
139 |
140 | if (!unvisitedNeighbors.empty())
141 | {
142 | // Randomly select a neighbor
143 | auto [nextX, nextY] = unvisitedNeighbors[esp_random() % unvisitedNeighbors.size()];
144 |
145 | // Remove the wall between the current cell and the chosen cell
146 | if (nextX == x + 1)
147 | {
148 | maze[y][x].rightWall = false;
149 | maze[nextY][nextX].leftWall = false;
150 | }
151 | else if (nextX == x - 1)
152 | {
153 | maze[y][x].leftWall = false;
154 | maze[nextY][nextX].rightWall = false;
155 | }
156 | else if (nextY == y + 1)
157 | {
158 | maze[y][x].bottomWall = false;
159 | maze[nextY][nextX].topWall = false;
160 | }
161 | else if (nextY == y - 1)
162 | {
163 | maze[y][x].topWall = false;
164 | maze[nextY][nextX].bottomWall = false;
165 | }
166 |
167 | maze[nextY][nextX].visited = true;
168 | stack.push({nextX, nextY});
169 | }
170 | else
171 | {
172 | stack.pop();
173 | }
174 | }
175 | }
176 | void drawMaze(const std::vector> &path)
177 | {
178 | for (int y = 0; y < mazeHeight; y++)
179 | {
180 | for (int x = 0; x < mazeWidth; x++)
181 | {
182 | // Calculate the top left corner of the cell
183 | int x0 = x * cellSize;
184 | int y0 = y * cellSize;
185 |
186 | // Draw the walls of the cell
187 | if (maze[y][x].topWall)
188 | {
189 | tft->drawLine(x0, y0, x0 + cellSize, y0, TFT_WHITE); // Top wall
190 | }
191 | if (maze[y][x].bottomWall)
192 | {
193 | tft->drawLine(x0, y0 + cellSize, x0 + cellSize, y0 + cellSize, TFT_WHITE); // Bottom wall
194 | }
195 | if (maze[y][x].leftWall)
196 | {
197 | tft->drawLine(x0, y0, x0, y0 + cellSize, TFT_WHITE); // Left wall
198 | }
199 | if (maze[y][x].rightWall)
200 | {
201 | tft->drawLine(x0 + cellSize, y0, x0 + cellSize, y0 + cellSize, TFT_WHITE); // Right wall
202 | }
203 | }
204 | }
205 |
206 | // Draw the solution path in yellow
207 | for (size_t i = 0; i < path.size() - 1; ++i)
208 | {
209 | // Coordinates of the current cell
210 | int x0 = path[i].first * cellSize + cellSize / 2;
211 | int y0 = path[i].second * cellSize + cellSize / 2;
212 |
213 | // Coordinates of the next cell
214 | int x1 = path[i + 1].first * cellSize + cellSize / 2;
215 | int y1 = path[i + 1].second * cellSize + cellSize / 2;
216 |
217 | // Check if the next cell is a direct neighbor of the current cell
218 | bool isNeighbor = (path[i].first == path[i + 1].first && abs(path[i].second - path[i + 1].second) == 1) ||
219 | (path[i].second == path[i + 1].second && abs(path[i].first - path[i + 1].first) == 1);
220 |
221 | // Draw line only if the next cell is a neighbor
222 | if (isNeighbor)
223 | {
224 | tft->drawLine(x0, y0, x1, y1, TFT_YELLOW);
225 | tft->output();
226 | }
227 | }
228 | if (!path.empty())
229 | {
230 | // Get the coordinates of the last cell in the path
231 | auto [lastX, lastY] = path.back();
232 | int centerX = lastX * cellSize + cellSize / 2;
233 | int centerY = lastY * cellSize + cellSize / 2;
234 |
235 | // Draw a yellow circle at the end of the path
236 | int radius = cellSize / 4; // Radius of the circle
237 | tft->fillCircle(centerX, centerY, radius, TFT_YELLOW);
238 | }
239 |
240 | tft->output();
241 | }
242 |
243 | void setupMaze()
244 | {
245 | // Adjusted dimensions to account for padding
246 | mazeWidth = (tft->width() - paddingSize) / cellSize; // Ensure odd number
247 | mazeHeight = (tft->height() - paddingSize) / cellSize; // Ensure odd number
248 |
249 | // Ensure dimensions are odd numbers
250 | if (mazeWidth % 2 == 0)
251 | {
252 | mazeWidth--;
253 | }
254 | if (mazeHeight % 2 == 0)
255 | {
256 | mazeHeight--;
257 | }
258 |
259 | // Allocate memory for the maze grid
260 | maze.resize(mazeHeight, std::vector(mazeWidth));
261 |
262 | // Generate and draw the maze
263 | generateMaze();
264 | auto path = solveMaze();
265 |
266 | drawMaze(path);
267 | }
268 |
--------------------------------------------------------------------------------
/examples/4x1Screens/pong/Fun_Games20pt7b.h:
--------------------------------------------------------------------------------
1 | const uint8_t Fun_Games20pt7bBitmaps[] PROGMEM = {
2 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x38,
3 | 0xC2, 0x10, 0x7F, 0xFF, 0xFF, 0xC0, 0xEF, 0xDF, 0xBF, 0x7E, 0xFD, 0xFB,
4 | 0x80, 0x01, 0x80, 0x80, 0x03, 0x83, 0xC0, 0x1E, 0x0E, 0x00, 0x70, 0x38,
5 | 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80, 0x1C, 0x1E, 0x1F, 0xFF, 0xFF, 0x7F,
6 | 0xFF, 0xFD, 0xFF, 0xFF, 0xF0, 0x38, 0x1C, 0x00, 0xE0, 0xF0, 0x03, 0x83,
7 | 0x80, 0x1E, 0x0E, 0x00, 0x78, 0x38, 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80,
8 | 0x1C, 0x1E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x38,
9 | 0x1C, 0x00, 0xE0, 0x70, 0x03, 0x83, 0xC0, 0x0E, 0x0E, 0x00, 0x78, 0x38,
10 | 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00,
11 | 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFE, 0x03, 0xFF, 0xFC,
12 | 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF0, 0x0F, 0xFF, 0xF0, 0x0F, 0x80, 0x00,
13 | 0x1F, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
14 | 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
15 | 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
16 | 0x00, 0x00, 0xF8, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0,
17 | 0x3F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0x80, 0x0F, 0x00, 0x00, 0x0F, 0x00,
18 | 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0xFC, 0x1F, 0xF8, 0x3B, 0xF0, 0xF7,
19 | 0xE1, 0xEF, 0xC7, 0x9F, 0x8F, 0x00, 0x3C, 0x00, 0x78, 0x01, 0xE0, 0x03,
20 | 0xC0, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x80,
21 | 0x1E, 0x00, 0x3C, 0x00, 0x7B, 0xF1, 0xE7, 0xE3, 0xCF, 0xCF, 0x1F, 0x9E,
22 | 0x3F, 0x78, 0x7E, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F,
23 | 0xFF, 0xF8, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00,
24 | 0x00, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
25 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3E, 0x3E, 0x00, 0xF8, 0xF8,
26 | 0x03, 0xE3, 0xE0, 0x0F, 0x8F, 0xC0, 0x3E, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF,
27 | 0xE0, 0xFF, 0xFF, 0x81, 0xFF, 0xFE, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8,
28 | 0x07, 0xFF, 0x0F, 0xFE, 0x3F, 0xFC, 0x7F, 0xF0, 0xFF, 0xE0, 0xFC, 0x00,
29 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
30 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
31 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
32 | 0xFC, 0x00, 0xFF, 0xE0, 0x7F, 0xF0, 0x3F, 0xFC, 0x0F, 0xFE, 0x07, 0xFF,
33 | 0xFF, 0xE0, 0x7F, 0xF0, 0x1F, 0xFC, 0x0F, 0xFE, 0x07, 0xFF, 0x00, 0x3F,
34 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
35 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
36 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
37 | 0x00, 0x3F, 0x07, 0xFF, 0x0F, 0xFE, 0x1F, 0xFC, 0x7F, 0xF0, 0xFF, 0xE0,
38 | 0x0C, 0x0B, 0x47, 0xF8, 0xFC, 0xFF, 0xFF, 0xF3, 0xF1, 0xFE, 0x2D, 0x03,
39 | 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0, 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00,
40 | 0x0F, 0x80, 0x00, 0x7C, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0x00, 0xFF, 0xFF,
41 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
42 | 0x7C, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0,
43 | 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x0F, 0x80, 0x00, 0xFF, 0xFF, 0xFF,
44 | 0xFB, 0xDC, 0xC4, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
45 | 0x80, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x18, 0x00, 0x70, 0x03, 0xC0, 0x0E,
46 | 0x00, 0x78, 0x01, 0xC0, 0x07, 0x00, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x1C,
47 | 0x00, 0xF0, 0x03, 0x80, 0x0E, 0x00, 0x78, 0x01, 0xC0, 0x0F, 0x00, 0x38,
48 | 0x01, 0xE0, 0x07, 0x00, 0x1C, 0x00, 0xF0, 0x03, 0x80, 0x1E, 0x00, 0x70,
49 | 0x01, 0xC0, 0x0F, 0x00, 0x38, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
50 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F,
51 | 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00,
52 | 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF,
53 | 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF,
54 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
55 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0,
56 | 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F,
57 | 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC0, 0xF0, 0x1C, 0x03, 0x00, 0xC0,
58 | 0x10, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
59 | 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
60 | 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF,
61 | 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
62 | 0x00, 0x00, 0xFC, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x01, 0xFF,
63 | 0xFF, 0x01, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
64 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07,
65 | 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
66 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
67 | 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x1F, 0x87, 0xFF, 0xF1, 0xFF, 0xFC,
68 | 0x7F, 0xFF, 0x0F, 0xFF, 0xC3, 0xFF, 0xE0, 0xF8, 0x03, 0xFF, 0x00, 0x7F,
69 | 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF,
70 | 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF,
71 | 0x80, 0x3F, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
72 | 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0,
73 | 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x3C, 0x00, 0x03, 0x80,
74 | 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x08, 0x07, 0xFF, 0xFE,
75 | 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE1, 0xFF, 0xFF, 0x83, 0xFF, 0xFE, 0x0F,
76 | 0xE0, 0x00, 0x3F, 0x80, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF,
77 | 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xC0, 0x00,
78 | 0x1F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x07,
79 | 0xE0, 0x00, 0x0F, 0x80, 0x7F, 0xFF, 0x01, 0xFF, 0xFC, 0x07, 0xFF, 0xF8,
80 | 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF,
81 | 0xFF, 0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, 0x7C, 0x00, 0x03, 0xE0, 0x00,
82 | 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
83 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
84 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
85 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
86 | 0xFF, 0xF8, 0x7F, 0xFF, 0x0F, 0xFF, 0xE0, 0xFF, 0xF8, 0x00, 0x1F, 0x00,
87 | 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00,
88 | 0x1F, 0x80, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00,
89 | 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01,
90 | 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x1E, 0x00, 0x03,
91 | 0x80, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xFF,
92 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
93 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
94 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03,
95 | 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF,
96 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
98 | 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF,
99 | 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100 | 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0,
101 | 0x00, 0x3E, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0x9F, 0xFF, 0xFD, 0xFF, 0xFF,
102 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
103 | 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00,
104 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xC4, 0x20, 0x00, 0x08,
105 | 0x01, 0xC0, 0x3E, 0x03, 0xF0, 0x7F, 0x87, 0xF0, 0xFF, 0x1F, 0xE0, 0xFC,
106 | 0x07, 0xC0, 0x38, 0x01, 0xF0, 0x0F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFC,
107 | 0x07, 0xF8, 0x0F, 0xC0, 0x1E, 0x00, 0x70, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
108 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F,
109 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
110 | 0x80, 0x07, 0x00, 0x3E, 0x01, 0xF8, 0x0F, 0xF0, 0x1F, 0xC0, 0x7F, 0x80,
111 | 0xFF, 0x01, 0xF8, 0x07, 0xC0, 0x0E, 0x01, 0xF0, 0x1F, 0x83, 0xFC, 0x7F,
112 | 0x87, 0xF0, 0xFF, 0x07, 0xE0, 0x3C, 0x01, 0xC0, 0x08, 0x00, 0x00, 0xFF,
113 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
114 | 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x3F, 0xFC, 0x07,
115 | 0xFF, 0x80, 0xFF, 0xF0, 0x1F, 0xFE, 0x03, 0xFF, 0xC0, 0x00, 0x00, 0x00,
116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x1F,
117 | 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
118 | 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x3F, 0xC7, 0xE3,
119 | 0xFC, 0x7E, 0x30, 0xC7, 0xE3, 0x3C, 0x7E, 0x37, 0xC7, 0xE3, 0xEC, 0x7E,
120 | 0x3C, 0xC7, 0xE3, 0x8C, 0x7E, 0x38, 0xC7, 0xE3, 0x00, 0x7E, 0x20, 0x07,
121 | 0xE4, 0x00, 0x7E, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122 | 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 | 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x03, 0x1F, 0xF8, 0x3C,
124 | 0xFF, 0xC1, 0xF7, 0xFE, 0x1F, 0xFF, 0xF1, 0xFD, 0xFF, 0x9F, 0xCF, 0xFD,
125 | 0xFC, 0x7F, 0xEF, 0xC3, 0xFF, 0xFC, 0x1F, 0xFF, 0xE0, 0xFF, 0xFE, 0x07,
126 | 0xFF, 0xE0, 0x3F, 0xFE, 0x01, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0x7F, 0xF0,
127 | 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0x07, 0x80, 0x00, 0x38, 0x00, 0x01,
128 | 0x80, 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
129 | 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C, 0x03, 0xE3,
130 | 0xE0, 0x3E, 0x1F, 0x03, 0xE0, 0xF8, 0x7F, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F,
131 | 0xFF, 0xF0, 0xFF, 0xFF, 0x87, 0xFF, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xDF,
132 | 0x00, 0xFC, 0xF8, 0x0F, 0xC7, 0xC0, 0xFE, 0x3E, 0x07, 0xE1, 0xF0, 0x7E,
133 | 0x0F, 0x87, 0xE0, 0x7C, 0x7F, 0x03, 0xE3, 0xF0, 0x1F, 0x3F, 0x00, 0x03,
134 | 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00,
135 | 0x03, 0xC0, 0x00, 0x04, 0x00, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F,
136 | 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F,
137 | 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00,
138 | 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x3E, 0xF8, 0x03,
139 | 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF,
140 | 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
141 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0,
142 | 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80,
143 | 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00,
144 | 0x7F, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFF,
145 | 0xC7, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
146 | 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
147 | 0xFC, 0xFF, 0xF0, 0xFF, 0xE0, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
149 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
150 | 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3F,
151 | 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8, 0xFF, 0xF8, 0x3F, 0xFC, 0x0F, 0x80,
152 | 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00,
153 | 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xF1,
154 | 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00,
155 | 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x1F, 0xFF, 0x83, 0xFF, 0xF8, 0x7F,
156 | 0xFF, 0x8F, 0xFF, 0xF9, 0xFF, 0xFF, 0xA0, 0x1F, 0xF8, 0x01, 0xFF, 0x80,
157 | 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
158 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x08,
159 | 0x00, 0x00, 0x40, 0x00, 0x06, 0x00, 0x00, 0x70, 0x00, 0x07, 0x80, 0x00,
160 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
161 | 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03,
162 | 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
163 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
164 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80,
165 | 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x38, 0x00, 0x00,
166 | 0xC0, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
167 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
168 | 0xDE, 0x71, 0x84, 0x20, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF8, 0x7F, 0xF0,
169 | 0x7F, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00,
170 | 0xF8, 0x01, 0xF0, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F,
171 | 0xE0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC,
172 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xC7, 0xFC, 0x0F, 0xE0, 0x1E, 0x00,
173 | 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x07, 0x00, 0x00, 0x3E, 0x00,
174 | 0x00, 0xFC, 0xF8, 0x07, 0xE3, 0xE0, 0x3F, 0x8F, 0x81, 0xFC, 0x3E, 0x0F,
175 | 0xE0, 0xF8, 0x7F, 0x03, 0xE3, 0xF8, 0x0F, 0x9F, 0xC0, 0x3E, 0xFE, 0x00,
176 | 0xFF, 0xF0, 0x03, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0xFF,
177 | 0xE0, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x3F, 0x7F, 0x00, 0xF8, 0xFC,
178 | 0x03, 0xE1, 0xF8, 0x0F, 0x87, 0xF0, 0x3E, 0x0F, 0xC0, 0xF8, 0x1F, 0x83,
179 | 0xE0, 0x7F, 0x0F, 0x80, 0xFC, 0x3E, 0x01, 0xF8, 0xF8, 0x03, 0xF1, 0xE0,
180 | 0x0F, 0xC3, 0x80, 0x1F, 0x86, 0x00, 0x3F, 0x18, 0x00, 0xFC, 0x20, 0x01,
181 | 0xE0, 0x80, 0x02, 0x00, 0x80, 0x00, 0x38, 0x00, 0x0F, 0x80, 0x03, 0xE0,
182 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00,
183 | 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
184 | 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
185 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
186 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70,
187 | 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F,
188 | 0xE0, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x3F,
189 | 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x1F,
190 | 0xFF, 0xFF, 0x8F, 0xFF, 0xF7, 0xEF, 0xDF, 0xFB, 0xFF, 0xEF, 0xFC, 0xFF,
191 | 0xE7, 0xFE, 0x3F, 0xE3, 0xFF, 0x0F, 0xE1, 0xFF, 0x87, 0xF0, 0xFF, 0xC1,
192 | 0xF0, 0x7F, 0xE0, 0x70, 0x3F, 0xF0, 0x10, 0x1F, 0xF8, 0x00, 0x0F, 0xFC,
193 | 0x00, 0x07, 0xFE, 0x00, 0x03, 0xE0, 0x80, 0x00, 0x10, 0x00, 0x03, 0x00,
194 | 0x00, 0x70, 0x01, 0xFF, 0x00, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xE0,
195 | 0x1F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F, 0xFE, 0x0F, 0xFF, 0xE1, 0xFF, 0xFE,
196 | 0x3F, 0xFF, 0xE7, 0xFE, 0xFE, 0xFF, 0xCF, 0xDF, 0xF8, 0xFF, 0xFF, 0x0F,
197 | 0xFF, 0xE1, 0xFF, 0xFC, 0x1F, 0xFF, 0x81, 0xFF, 0xF0, 0x1F, 0xFE, 0x01,
198 | 0xFF, 0xC0, 0x1F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x03, 0x80, 0x00,
199 | 0x30, 0x00, 0x02, 0x00, 0x00, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03,
201 | 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0,
202 | 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
203 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
204 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
205 | 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0,
206 | 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07,
207 | 0xCF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x8F,
208 | 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80,
209 | 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00,
210 | 0x3E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
211 | 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03,
212 | 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07,
213 | 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xF0, 0x0F,
214 | 0xFF, 0xFF, 0xF7, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xF8, 0x3F, 0xFF,
215 | 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x1F, 0xE0, 0x01, 0xF8,
216 | 0x00, 0x1E, 0x00, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF,
217 | 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F,
218 | 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07, 0xCF, 0xBF, 0xFF, 0x3E,
219 | 0x7F, 0xFC, 0xF8, 0xFF, 0xF3, 0xE3, 0xFF, 0x8F, 0x87, 0xFE, 0x3E, 0x1F,
220 | 0x00, 0xF8, 0x3E, 0x03, 0xE0, 0xFC, 0x0F, 0x81, 0xF0, 0x3E, 0x03, 0xE0,
221 | 0xF8, 0x0F, 0x83, 0xE0, 0x1F, 0x0F, 0x80, 0x7E, 0x3E, 0x00, 0xF8, 0x00,
222 | 0x03, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x03, 0xFF,
223 | 0xFE, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0x81, 0xFF, 0xFE,
224 | 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00,
225 | 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF,
226 | 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x3F, 0x00, 0x00, 0x7C, 0x00,
227 | 0x01, 0xF8, 0x00, 0x07, 0xE0, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x07, 0xFF,
228 | 0xFC, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xE1, 0xFF,
229 | 0xFF, 0xF0, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80,
230 | 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F,
231 | 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00,
232 | 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8,
233 | 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00,
234 | 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0,
235 | 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00,
236 | 0x1C, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x02, 0x00,
237 | 0x00, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF,
238 | 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00,
239 | 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC,
240 | 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07,
241 | 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
242 | 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x3F,
243 | 0x80, 0x07, 0xF8, 0x00, 0xFF, 0x80, 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F,
244 | 0xF8, 0x07, 0xEF, 0x80, 0xFC, 0xF8, 0x1F, 0x8F, 0x83, 0xF0, 0xF8, 0x7F,
245 | 0x0F, 0x8F, 0xE0, 0xF9, 0xFC, 0x0F, 0xBF, 0x80, 0xFB, 0xF0, 0x0F, 0xFE,
246 | 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, 0x80, 0x0F, 0xF0, 0x00, 0xFE,
247 | 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0E,
248 | 0x00, 0x00, 0xC0, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0xF8, 0x00,
249 | 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x02, 0x03, 0xFF, 0x01, 0x81, 0xFF, 0x81,
250 | 0xC0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE1, 0xFC, 0x3F, 0xF1, 0xFF, 0x1F, 0xF8,
251 | 0xFF, 0x8F, 0xFC, 0xFF, 0xE7, 0xFE, 0xFF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF,
252 | 0xFE, 0x3F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x01, 0xFF,
253 | 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x03,
254 | 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00,
255 | 0x07, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x20, 0xFC,
256 | 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F, 0x00, 0xFC, 0x3F, 0x81, 0xFC, 0x1F,
257 | 0x83, 0xF8, 0x0F, 0xC3, 0xF0, 0x07, 0xE7, 0xE0, 0x07, 0xFF, 0xE0, 0x03,
258 | 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
259 | 0x7E, 0x00, 0x00, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x03, 0xFF, 0xC0, 0x03,
260 | 0xFF, 0xC0, 0x07, 0xE7, 0xE0, 0x0F, 0xC3, 0xF0, 0x1F, 0xC3, 0xF8, 0x1F,
261 | 0x81, 0xF8, 0x3F, 0x00, 0xFC, 0x7E, 0x00, 0x7E, 0xFE, 0x00, 0x7F, 0xFE,
262 | 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F, 0x00, 0xFC, 0x1F, 0x81, 0xF8, 0x1F,
263 | 0xC3, 0xF8, 0x0F, 0xC3, 0xF0, 0x07, 0xE7, 0xE0, 0x03, 0xFF, 0xC0, 0x03,
264 | 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00,
265 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
266 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
267 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
268 | 0x7C, 0x00, 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, 0x00, 0x40, 0x00, 0xFF,
269 | 0xFF, 0xDF, 0xFF, 0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0xFC, 0x00,
270 | 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x07,
271 | 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x03, 0xF0, 0x00, 0xFC,
272 | 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x01, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
273 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,
274 | 0xFE, 0x3F, 0xF0, 0xFF, 0x83, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03,
275 | 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00,
276 | 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80,
277 | 0x3E, 0x00, 0xF8, 0x03, 0xFE, 0x0F, 0xFC, 0x3F, 0xF8, 0xFF, 0xF3, 0xFF,
278 | 0xF0, 0x60, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xE0, 0x03,
279 | 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00,
280 | 0x1C, 0x00, 0x78, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x78,
281 | 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x78, 0x00, 0xE0, 0x03,
282 | 0xC0, 0x07, 0x00, 0x18, 0xFF, 0xFC, 0xFF, 0xF1, 0xFF, 0xC3, 0xFF, 0x07,
283 | 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0,
284 | 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0,
285 | 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C,
286 | 0x1F, 0xF0, 0xFF, 0xC7, 0xFF, 0x3F, 0xFF, 0xFF, 0xF0, 0x01, 0xF8, 0x00,
287 | 0x3F, 0x80, 0x03, 0xFC, 0x00, 0x7F, 0xE0, 0x0F, 0x9E, 0x00, 0xF1, 0xF0,
288 | 0x1F, 0x0F, 0x01, 0xE0, 0xF8, 0x3E, 0x07, 0xC7, 0xC0, 0x3C, 0x78, 0x03,
289 | 0xEF, 0x80, 0x1E, 0xF0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
290 | 0xE0, 0xF1, 0xE3, 0x8F, 0x1C, 0x30, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
291 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0,
292 | 0x03, 0xFF, 0x03, 0x1F, 0xF8, 0x3C, 0xFF, 0xC1, 0xF7, 0xFE, 0x1F, 0xFF,
293 | 0xF1, 0xFD, 0xFF, 0x9F, 0xCF, 0xFD, 0xFC, 0x7F, 0xEF, 0xC3, 0xFF, 0xFC,
294 | 0x1F, 0xFF, 0xE0, 0xFF, 0xFE, 0x07, 0xFF, 0xE0, 0x3F, 0xFE, 0x01, 0xFF,
295 | 0xF0, 0x0F, 0xFF, 0x00, 0x7F, 0xF0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00,
296 | 0x07, 0x80, 0x00, 0x38, 0x00, 0x01, 0x80, 0x00, 0x08, 0x00, 0x00, 0x40,
297 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, 0xFF,
298 | 0xCF, 0xFF, 0xFC, 0x7C, 0x03, 0xE3, 0xE0, 0x3E, 0x1F, 0x03, 0xE0, 0xF8,
299 | 0x7F, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0xFF, 0xFF, 0x87, 0xFF,
300 | 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xDF, 0x00, 0xFC, 0xF8, 0x0F, 0xC7, 0xC0,
301 | 0xFE, 0x3E, 0x07, 0xE1, 0xF0, 0x7E, 0x0F, 0x87, 0xE0, 0x7C, 0x7F, 0x03,
302 | 0xE3, 0xF0, 0x1F, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xF8,
303 | 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00, 0x03, 0xC0, 0x00, 0x04, 0x00, 0x00,
304 | 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF,
305 | 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80,
306 | 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8,
307 | 0x00, 0x0F, 0x80, 0x3E, 0xF8, 0x03, 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF,
308 | 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE,
309 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
310 | 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F,
311 | 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF,
312 | 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF,
313 | 0xFF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFF, 0xC7, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
314 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
315 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xF0, 0xFF, 0xE0, 0xFF,
316 | 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
317 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
318 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0x80,
319 | 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8,
320 | 0xFF, 0xF8, 0x3F, 0xFC, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E,
321 | 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80,
322 | 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF,
323 | 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8,
324 | 0x1F, 0xFF, 0x83, 0xFF, 0xF8, 0x7F, 0xFF, 0x8F, 0xFF, 0xF9, 0xFF, 0xFF,
325 | 0xA0, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F,
326 | 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
327 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x06, 0x00,
328 | 0x00, 0x70, 0x00, 0x07, 0x80, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
329 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80,
330 | 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
331 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
332 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
333 | 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x00,
334 | 0x0F, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x00, 0x02, 0x00, 0x00, 0x10,
335 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
336 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x71, 0x84, 0x20, 0x7F, 0xFE,
337 | 0x7F, 0xFC, 0x7F, 0xF8, 0x7F, 0xF0, 0x7F, 0xE0, 0x07, 0xC0, 0x0F, 0x80,
338 | 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xF0, 0x07,
339 | 0xE0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F, 0xE0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF,
340 | 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF,
341 | 0xC7, 0xFC, 0x0F, 0xE0, 0x1E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80,
342 | 0x00, 0x07, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xFC, 0xF8, 0x07, 0xE3, 0xE0,
343 | 0x3F, 0x8F, 0x81, 0xFC, 0x3E, 0x0F, 0xE0, 0xF8, 0x7F, 0x03, 0xE3, 0xF8,
344 | 0x0F, 0x9F, 0xC0, 0x3E, 0xFE, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0x80, 0x0F,
345 | 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0xC0, 0x0F, 0xFF,
346 | 0x80, 0x3F, 0x7F, 0x00, 0xF8, 0xFC, 0x03, 0xE1, 0xF8, 0x0F, 0x87, 0xF0,
347 | 0x3E, 0x0F, 0xC0, 0xF8, 0x1F, 0x83, 0xE0, 0x7F, 0x0F, 0x80, 0xFC, 0x3E,
348 | 0x01, 0xF8, 0xF8, 0x03, 0xF1, 0xE0, 0x0F, 0xC3, 0x80, 0x1F, 0x86, 0x00,
349 | 0x3F, 0x18, 0x00, 0xFC, 0x20, 0x01, 0xE0, 0x80, 0x02, 0x00, 0x80, 0x00,
350 | 0x38, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
351 | 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
352 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00,
353 | 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
354 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80,
355 | 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7F,
356 | 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xF8, 0x00, 0x3F,
357 | 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x3F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x1F,
358 | 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xF7, 0xEF,
359 | 0xDF, 0xFB, 0xFF, 0xEF, 0xFC, 0xFF, 0xE7, 0xFE, 0x3F, 0xE3, 0xFF, 0x0F,
360 | 0xE1, 0xFF, 0x87, 0xF0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE0, 0x70, 0x3F, 0xF0,
361 | 0x10, 0x1F, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x00, 0x03, 0xE0,
362 | 0x80, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x70, 0x01, 0xFF, 0x00, 0x3F,
363 | 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xE0, 0x1F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F,
364 | 0xFE, 0x0F, 0xFF, 0xE1, 0xFF, 0xFE, 0x3F, 0xFF, 0xE7, 0xFE, 0xFE, 0xFF,
365 | 0xCF, 0xDF, 0xF8, 0xFF, 0xFF, 0x0F, 0xFF, 0xE1, 0xFF, 0xFC, 0x1F, 0xFF,
366 | 0x81, 0xFF, 0xF0, 0x1F, 0xFE, 0x01, 0xFF, 0xC0, 0x1F, 0xF8, 0x01, 0xFF,
367 | 0x00, 0x3F, 0xE0, 0x03, 0x80, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x40,
368 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
369 | 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF,
370 | 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00,
371 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
372 | 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
373 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF,
374 | 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00,
375 | 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07, 0xCF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC,
376 | 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0xF8,
377 | 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x00,
378 | 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
379 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE,
380 | 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC,
381 | 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8,
382 | 0x03, 0xFF, 0x00, 0x7F, 0xF0, 0x0F, 0xFF, 0xFF, 0xF7, 0xFF, 0xFE, 0x7F,
383 | 0xFF, 0xC7, 0xFF, 0xF8, 0x3F, 0xFF, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03,
384 | 0xFC, 0x00, 0x1F, 0xE0, 0x01, 0xF8, 0x00, 0x1E, 0x00, 0x01, 0x80, 0xFF,
385 | 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF,
386 | 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3,
387 | 0xE0, 0x07, 0xCF, 0xBF, 0xFF, 0x3E, 0x7F, 0xFC, 0xF8, 0xFF, 0xF3, 0xE3,
388 | 0xFF, 0x8F, 0x87, 0xFE, 0x3E, 0x1F, 0x00, 0xF8, 0x3E, 0x03, 0xE0, 0xFC,
389 | 0x0F, 0x81, 0xF0, 0x3E, 0x03, 0xE0, 0xF8, 0x0F, 0x83, 0xE0, 0x1F, 0x0F,
390 | 0x80, 0x7E, 0x3E, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x07, 0x00, 0x00,
391 | 0x08, 0x00, 0x00, 0x40, 0x03, 0xFF, 0xFE, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF,
392 | 0xE0, 0x7F, 0xFF, 0x81, 0xFF, 0xFE, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00,
393 | 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB,
394 | 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0x80,
395 | 0x00, 0x3F, 0x00, 0x00, 0x7C, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0xFF,
396 | 0xFF, 0x81, 0xFF, 0xFF, 0x07, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF,
397 | 0xE0, 0x03, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFC, 0x1F,
398 | 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0,
399 | 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00,
400 | 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00,
401 | 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03,
402 | 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00,
403 | 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F,
404 | 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x01, 0x80, 0x00,
405 | 0x00, 0x30, 0x00, 0x00, 0x02, 0x00, 0x00, 0xF8, 0x00, 0xFF, 0xC0, 0x07,
406 | 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0,
407 | 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F,
408 | 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00,
409 | 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
410 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
411 | 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x3F, 0x80, 0x07, 0xF8, 0x00, 0xFF, 0x80,
412 | 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F, 0xF8, 0x07, 0xEF, 0x80, 0xFC, 0xF8,
413 | 0x1F, 0x8F, 0x83, 0xF0, 0xF8, 0x7F, 0x0F, 0x8F, 0xE0, 0xF9, 0xFC, 0x0F,
414 | 0xBF, 0x80, 0xFB, 0xF0, 0x0F, 0xFE, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00,
415 | 0xFF, 0x80, 0x0F, 0xF0, 0x00, 0xFE, 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00,
416 | 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x00, 0x08, 0x00,
417 | 0x00, 0x80, 0x00, 0x00, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x02,
418 | 0x03, 0xFF, 0x01, 0x81, 0xFF, 0x81, 0xC0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE1,
419 | 0xFC, 0x3F, 0xF1, 0xFF, 0x1F, 0xF8, 0xFF, 0x8F, 0xFC, 0xFF, 0xE7, 0xFE,
420 | 0xFF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFE, 0x0F, 0xFF,
421 | 0xFF, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x1F,
422 | 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00,
423 | 0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x01, 0xC0, 0x00,
424 | 0x00, 0x60, 0x00, 0x00, 0x20, 0xFC, 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F,
425 | 0x00, 0xFC, 0x3F, 0x81, 0xFC, 0x1F, 0x83, 0xF8, 0x0F, 0xC3, 0xF0, 0x07,
426 | 0xE7, 0xE0, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00,
427 | 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0x00, 0x01,
428 | 0xFF, 0x80, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xC0, 0x07, 0xE7, 0xE0, 0x0F,
429 | 0xC3, 0xF0, 0x1F, 0xC3, 0xF8, 0x1F, 0x81, 0xF8, 0x3F, 0x00, 0xFC, 0x7E,
430 | 0x00, 0x7E, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F,
431 | 0x00, 0xFC, 0x1F, 0x81, 0xF8, 0x1F, 0xC3, 0xF8, 0x0F, 0xC3, 0xF0, 0x07,
432 | 0xE7, 0xE0, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00,
433 | 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
434 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
435 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
436 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x78, 0x00, 0x00,
437 | 0x70, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFB, 0xFF, 0xFF,
438 | 0x7F, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8,
439 | 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x07, 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x00,
440 | 0x1F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x01,
441 | 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
442 | 0xFF, 0xFF, 0x00, 0xFF, 0xE0, 0x7F, 0xF8, 0x1F, 0xFE, 0x07, 0xFF, 0x01,
443 | 0xFF, 0xC0, 0x3F, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03,
444 | 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F,
445 | 0xC0, 0x07, 0xF8, 0x00, 0xFF, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F,
446 | 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
447 | 0x80, 0x03, 0xFF, 0x80, 0x3F, 0xF8, 0x03, 0xFF, 0xC0, 0x1F, 0xFC, 0x01,
448 | 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF,
449 | 0xE0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x07, 0xFF, 0x00, 0x7F, 0xF0, 0x00,
450 | 0x7E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00,
451 | 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00,
452 | 0xFF, 0x00, 0x1F, 0xE0, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01,
453 | 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x3F, 0x00, 0xFF,
454 | 0xE0, 0x3F, 0xF8, 0x1F, 0xFE, 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0x00, 0x3F,
455 | 0x00, 0x0F, 0xF8, 0x03, 0xFF, 0xC3, 0x30, 0xFF, 0xF4, 0x07, 0xFC, 0x00,
456 | 0x1F, 0x00 };
457 |
458 | const GFXglyph Fun_Games20pt7bGlyphs[] PROGMEM = {
459 | { 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
460 | { 1, 5, 26, 9, 2, -25 }, // 0x21 '!'
461 | { 18, 7, 7, 11, 2, -23 }, // 0x22 '"'
462 | { 25, 22, 28, 25, 2, -25 }, // 0x23 '#'
463 | { 102, 24, 32, 27, 1, -27 }, // 0x24 '$'
464 | { 198, 15, 24, 18, 2, -23 }, // 0x25 '%'
465 | { 243, 22, 24, 25, 2, -23 }, // 0x26 '&'
466 | { 309, 3, 7, 6, 2, -23 }, // 0x27 '''
467 | { 312, 16, 30, 19, 2, -23 }, // 0x28 '('
468 | { 372, 16, 30, 20, 2, -23 }, // 0x29 ')'
469 | { 432, 10, 10, 13, 2, -24 }, // 0x2A '*'
470 | { 445, 21, 21, 23, 1, -23 }, // 0x2B '+'
471 | { 501, 5, 11, 9, 2, -4 }, // 0x2C ','
472 | { 508, 13, 5, 17, 2, -12 }, // 0x2D '-'
473 | { 517, 5, 5, 9, 2, -4 }, // 0x2E '.'
474 | { 521, 14, 29, 18, 2, -27 }, // 0x2F '/'
475 | { 572, 21, 24, 25, 2, -23 }, // 0x30 '0'
476 | { 635, 10, 30, 14, 2, -23 }, // 0x31 '1'
477 | { 673, 23, 24, 27, 2, -23 }, // 0x32 '2'
478 | { 742, 19, 24, 23, 2, -23 }, // 0x33 '3'
479 | { 799, 19, 31, 23, 2, -23 }, // 0x34 '4'
480 | { 873, 23, 24, 27, 2, -23 }, // 0x35 '5'
481 | { 942, 21, 24, 25, 2, -23 }, // 0x36 '6'
482 | { 1005, 19, 30, 20, 0, -23 }, // 0x37 '7'
483 | { 1077, 21, 24, 25, 2, -23 }, // 0x38 '8'
484 | { 1140, 21, 24, 25, 2, -23 }, // 0x39 '9'
485 | { 1203, 5, 21, 9, 2, -20 }, // 0x3A ':'
486 | { 1217, 5, 27, 9, 2, -20 }, // 0x3B ';'
487 | { 1234, 13, 21, 16, 2, -23 }, // 0x3C '<'
488 | { 1269, 19, 11, 23, 2, -18 }, // 0x3D '='
489 | { 1296, 13, 21, 16, 1, -23 }, // 0x3E '>'
490 | { 1331, 19, 24, 23, 2, -23 }, // 0x3F '?'
491 | { 1388, 20, 21, 24, 2, -23 }, // 0x40 '@'
492 | { 1441, 21, 30, 25, 2, -23 }, // 0x41 'A'
493 | { 1520, 21, 31, 25, 2, -23 }, // 0x42 'B'
494 | { 1602, 20, 24, 24, 2, -23 }, // 0x43 'C'
495 | { 1662, 19, 24, 23, 2, -23 }, // 0x44 'D'
496 | { 1719, 16, 24, 20, 2, -23 }, // 0x45 'E'
497 | { 1767, 18, 24, 22, 2, -23 }, // 0x46 'F'
498 | { 1821, 20, 24, 24, 2, -23 }, // 0x47 'G'
499 | { 1881, 21, 36, 25, 2, -29 }, // 0x48 'H'
500 | { 1976, 5, 31, 9, 2, -24 }, // 0x49 'I'
501 | { 1996, 15, 31, 18, 2, -23 }, // 0x4A 'J'
502 | { 2055, 22, 35, 23, 2, -27 }, // 0x4B 'K'
503 | { 2152, 18, 27, 22, 2, -26 }, // 0x4C 'L'
504 | { 2213, 25, 27, 29, 2, -26 }, // 0x4D 'M'
505 | { 2298, 19, 30, 23, 2, -26 }, // 0x4E 'N'
506 | { 2370, 21, 24, 25, 2, -23 }, // 0x4F 'O'
507 | { 2433, 22, 24, 25, 2, -23 }, // 0x50 'P'
508 | { 2499, 19, 31, 23, 2, -23 }, // 0x51 'Q'
509 | { 2573, 22, 28, 24, 2, -23 }, // 0x52 'R'
510 | { 2650, 23, 24, 27, 2, -23 }, // 0x53 'S'
511 | { 2719, 27, 30, 27, 0, -23 }, // 0x54 'T'
512 | { 2821, 21, 24, 25, 2, -23 }, // 0x55 'U'
513 | { 2884, 20, 31, 23, 2, -23 }, // 0x56 'V'
514 | { 2962, 25, 27, 29, 2, -23 }, // 0x57 'W'
515 | { 3047, 24, 24, 28, 2, -23 }, // 0x58 'X'
516 | { 3119, 24, 28, 28, 2, -23 }, // 0x59 'Y'
517 | { 3203, 19, 24, 22, 2, -23 }, // 0x5A 'Z'
518 | { 3260, 14, 30, 17, 2, -23 }, // 0x5B '['
519 | { 3313, 14, 29, 18, 2, -27 }, // 0x5C '\'
520 | { 3364, 14, 30, 17, 1, -23 }, // 0x5D ']'
521 | { 3417, 20, 13, 24, 2, -23 }, // 0x5E '^'
522 | { 3450, 17, 3, 20, 2, 4 }, // 0x5F '_'
523 | { 3457, 6, 8, 9, 2, -29 }, // 0x60 '`'
524 | { 3463, 21, 30, 25, 2, -23 }, // 0x61 'a'
525 | { 3542, 21, 31, 25, 2, -23 }, // 0x62 'b'
526 | { 3624, 20, 24, 24, 2, -23 }, // 0x63 'c'
527 | { 3684, 19, 24, 23, 2, -23 }, // 0x64 'd'
528 | { 3741, 16, 24, 20, 2, -23 }, // 0x65 'e'
529 | { 3789, 18, 24, 22, 2, -23 }, // 0x66 'f'
530 | { 3843, 20, 24, 24, 2, -23 }, // 0x67 'g'
531 | { 3903, 21, 36, 25, 2, -29 }, // 0x68 'h'
532 | { 3998, 5, 31, 9, 2, -24 }, // 0x69 'i'
533 | { 4018, 15, 31, 18, 2, -23 }, // 0x6A 'j'
534 | { 4077, 22, 35, 23, 2, -27 }, // 0x6B 'k'
535 | { 4174, 18, 27, 22, 2, -26 }, // 0x6C 'l'
536 | { 4235, 25, 27, 29, 2, -26 }, // 0x6D 'm'
537 | { 4320, 19, 30, 23, 2, -26 }, // 0x6E 'n'
538 | { 4392, 21, 24, 25, 2, -23 }, // 0x6F 'o'
539 | { 4455, 22, 24, 25, 2, -23 }, // 0x70 'p'
540 | { 4521, 19, 31, 23, 2, -23 }, // 0x71 'q'
541 | { 4595, 22, 28, 24, 2, -23 }, // 0x72 'r'
542 | { 4672, 23, 24, 27, 2, -23 }, // 0x73 's'
543 | { 4741, 27, 30, 27, 0, -23 }, // 0x74 't'
544 | { 4843, 21, 24, 25, 2, -23 }, // 0x75 'u'
545 | { 4906, 20, 31, 23, 2, -23 }, // 0x76 'v'
546 | { 4984, 25, 27, 29, 2, -23 }, // 0x77 'w'
547 | { 5069, 24, 24, 28, 2, -23 }, // 0x78 'x'
548 | { 5141, 24, 28, 28, 2, -23 }, // 0x79 'y'
549 | { 5225, 19, 24, 22, 2, -23 }, // 0x7A 'z'
550 | { 5282, 19, 30, 23, 2, -23 }, // 0x7B '{'
551 | { 5354, 2, 34, 6, 2, -26 }, // 0x7C '|'
552 | { 5363, 19, 30, 23, 2, -23 }, // 0x7D '}'
553 | { 5435, 19, 6, 23, 2, -19 } }; // 0x7E '~'
554 |
555 | const GFXfont Fun_Games20pt7b PROGMEM = {
556 | (uint8_t *)Fun_Games20pt7bBitmaps,
557 | (GFXglyph *)Fun_Games20pt7bGlyphs,
558 | 0x20, 0x7E, 40 };
559 |
560 | // Approx. 6122 bytes
561 |
--------------------------------------------------------------------------------
/examples/4x1Screens/pong/pong.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 | #include "Fun_Games20pt7b.h"
7 | #include "Fun_Games40pt7b.h"
8 |
9 | VirtualDisplay *tft;
10 | ScreenBuilder screens;
11 |
12 | void setup()
13 | {
14 | Serial.begin(115200);
15 |
16 | // Adjust this setup according to your actual screen layout
17 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
18 |
19 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
20 | tft->begin();
21 |
22 |
23 | playPong();
24 | }
25 |
26 | void loop()
27 | {
28 | }
29 |
30 | const int messageAreaWidth = 240; // Width of the message area on the left
31 | const int scoreAreaHeight = 50; // Height of the score area at the top
32 |
33 | void playPong()
34 | {
35 | const int paddleWidth = 20;
36 | const int paddleHeight = 50;
37 | const int ballSize = 8;
38 | int ballX, ballY; // Ball position
39 | int ballVelocityX = 12, ballVelocityY = 12; // Ball velocity
40 | int leftPaddleY, rightPaddleY; // Paddle positions
41 |
42 | // Initialize ball and paddles positions
43 | ballX = messageAreaWidth + (tft->width() - messageAreaWidth) / 2;
44 | ballY = scoreAreaHeight + (tft->height() - scoreAreaHeight) / 2;
45 | leftPaddleY = rightPaddleY = scoreAreaHeight + (tft->height() - scoreAreaHeight - paddleHeight) / 2;
46 |
47 | tft->fillScreen(TFT_BLACK); // Clear the screen
48 | drawScores(10, 10);
49 | drawMessage("Pong");
50 | tft->output();
51 | while (true)
52 | {
53 | // Clear the previous positions of the ball and paddles
54 | tft->fillRect(messageAreaWidth, leftPaddleY, paddleWidth, paddleHeight, TFT_BLACK); // Clear Left paddle
55 | tft->fillRect(tft->width() - paddleWidth, rightPaddleY, paddleWidth, paddleHeight, TFT_BLACK); // Clear Right paddle
56 | tft->fillCircle(ballX, ballY, ballSize, TFT_BLACK);
57 |
58 | // Update ball position
59 | ballX += ballVelocityX;
60 | ballY += ballVelocityY;
61 |
62 | // Check for ball collisions with the top and bottom of the screen
63 | if (ballY <= scoreAreaHeight + (ballSize * 2 + 5) || ballY >= tft->height() - ballSize)
64 | {
65 | ballVelocityY = -ballVelocityY;
66 | }
67 |
68 | // Update paddles position to follow the ball
69 | leftPaddleY = ballY - paddleHeight / 2;
70 | rightPaddleY = ballY - paddleHeight / 2;
71 |
72 | // Keep paddles within the screen bounds
73 | leftPaddleY = max(scoreAreaHeight, min(tft->height() - paddleHeight, leftPaddleY));
74 | rightPaddleY = max(scoreAreaHeight, min(tft->height() - paddleHeight, rightPaddleY));
75 |
76 | // Check for ball collisions with the paddles
77 | if ((ballX <= messageAreaWidth + paddleWidth + ballSize * 2 && ballY >= leftPaddleY && ballY <= leftPaddleY + paddleHeight) ||
78 | (ballX >= tft->width() - paddleWidth - ballSize && ballY >= rightPaddleY && ballY <= rightPaddleY + paddleHeight))
79 | {
80 | ballVelocityX = -ballVelocityX;
81 | ballVelocityY += esp_random() % 5;
82 | }
83 |
84 | // Draw the updated game state
85 | tft->fillRect(messageAreaWidth, leftPaddleY, paddleWidth, paddleHeight, 0xf818); // Left paddle
86 | tft->fillRect(tft->width() - paddleWidth, rightPaddleY, paddleWidth, paddleHeight, 0x07e6); // Right paddle
87 | tft->fillCircle(ballX, ballY, ballSize, 0xe7e0); // Ball
88 |
89 | // Update the display
90 | tft->output();
91 | }
92 | }
93 |
94 | void drawScores(int leftScore, int rightScore)
95 | {
96 | // Clear the score area
97 | tft->fillRoundRect(messageAreaWidth, 0, tft->width() - messageAreaWidth, scoreAreaHeight, 20, 0x17bb);
98 |
99 | // Set text properties and display scores
100 | tft->setTextColor(TFT_BLACK);
101 | tft->setFont(&Fun_Games20pt7b);
102 | tft->setCursor(messageAreaWidth + 3, 35);
103 | tft->print("Player 1: ");
104 | tft->print(leftScore);
105 | tft->setCursor(721, 35);
106 | tft->print("Player 2: ");
107 | tft->print(rightScore);
108 | }
109 |
110 | void drawMessage(const String &message)
111 | {
112 | // Clear the message area
113 | tft->fillRect(0, 0, messageAreaWidth, tft->height(), TFT_BLACK);
114 |
115 | // Set text properties and display the message
116 | tft->setFont(&Fun_Games40pt7b);
117 | tft->setTextColor(0xfec0);
118 | tft->setCursor(25, 150);
119 | tft->print(message);
120 | }
--------------------------------------------------------------------------------
/examples/4x1Screens/tetris/tetris.ino:
--------------------------------------------------------------------------------
1 | // Screen Layout : 4 screens on a single row
2 | // See the tutorial : https://youtu.be/eCfeJh9Pyns
3 | //
4 |
5 | #include "virtualScreen.h"
6 |
7 | VirtualDisplay *tft;
8 | ScreenBuilder screens;
9 |
10 | void setup()
11 | {
12 | Serial.begin(115200);
13 |
14 | // Adjust this setup according to your actual screen layout
15 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
16 |
17 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
18 | tft->begin();
19 |
20 | playTetris();
21 | }
22 |
23 | void loop()
24 | {
25 | }
26 |
27 | std::vector> updateGrid;
28 |
29 | // Define Tetromino shapes
30 | const int I[4][4] = {
31 | {0, 0, 0, 0},
32 | {1, 1, 1, 1},
33 | {0, 0, 0, 0},
34 | {0, 0, 0, 0}};
35 |
36 | const int O[4][4] = {
37 | {0, 0, 0, 0},
38 | {0, 1, 1, 0},
39 | {0, 1, 1, 0},
40 | {0, 0, 0, 0}};
41 |
42 | const int T[4][4] = {
43 | {0, 1, 0, 0},
44 | {1, 1, 1, 0},
45 | {0, 0, 0, 0},
46 | {0, 0, 0, 0}};
47 |
48 | const int S[4][4] = {
49 | {0, 1, 1, 0},
50 | {1, 1, 0, 0},
51 | {0, 0, 0, 0},
52 | {0, 0, 0, 0}};
53 |
54 | const int Z[4][4] = {
55 | {1, 1, 0, 0},
56 | {0, 1, 1, 0},
57 | {0, 0, 0, 0},
58 | {0, 0, 0, 0}};
59 |
60 | const int J[4][4] = {
61 | {1, 0, 0, 0},
62 | {1, 1, 1, 0},
63 | {0, 0, 0, 0},
64 | {0, 0, 0, 0}};
65 |
66 | const int L[4][4] = {
67 | {0, 0, 1, 0},
68 | {1, 1, 1, 0},
69 | {0, 0, 0, 0},
70 | {0, 0, 0, 0}};
71 |
72 | // Define colors for each tetromino shape
73 | const uint16_t tetrominoColors[7] = {
74 | TFT_RED, // Color for shape I
75 | TFT_GREEN, // Color for shape O
76 | TFT_BLUE, // Color for shape T
77 | TFT_YELLOW, // Color for shape S
78 | TFT_PURPLE, // Color for shape Z
79 | TFT_ORANGE, // Color for shape J
80 | TFT_CYAN // Color for shape L
81 | };
82 |
83 | const int blockSize = 20; // Size of each Tetris block in pixels
84 |
85 | const int (*tetrominoes[7])[4] = {I, O, T, S, Z, J, L};
86 |
87 | int tetrisWidth; // Width of the Tetris grid, set in setupTetris
88 | int tetrisHeight; // Height of the Tetris grid, set in setupTetris
89 | std::vector> grid; // Game grid
90 |
91 | struct Tetromino
92 | {
93 | int x, y; // Position
94 | int shape[4][4]; // Shape
95 | uint16_t color; // Color
96 | } currentTetromino;
97 |
98 | void playTetris()
99 | {
100 | setupTetris();
101 |
102 | while (true)
103 | {
104 | clearTetrominoPosition();
105 |
106 | // Attempt to move the tetromino down by incrementing its x position
107 | if (canPlace(currentTetromino.x + 1, currentTetromino.y, currentTetromino.shape))
108 | {
109 | currentTetromino.x++;
110 | }
111 | else
112 | {
113 | // If the tetromino cannot move down, place it on the grid
114 | placeTetromino();
115 | clearLines(); // Call the line-clearing function
116 | spawnTetromino(); // Spawn a new tetromino
117 | }
118 |
119 | placeTetromino();
120 | drawGrid();
121 |
122 | tft->output(); // Assuming this function outputs the virtual display to the actual display
123 | }
124 | }
125 |
126 | void clearLines()
127 | {
128 | for (int row = tetrisHeight - 1; row >= 0; row--)
129 | {
130 | bool rowFilled = true;
131 |
132 | // Check if the row is filled
133 | for (int col = 0; col < tetrisWidth; col++)
134 | {
135 | if (grid[row][col] == 0)
136 | {
137 | rowFilled = false;
138 | break;
139 | }
140 | }
141 |
142 | // Clear the row if it's filled
143 | if (rowFilled)
144 | {
145 | for (int y = row; y > 0; y--)
146 | {
147 | for (int x = 0; x < tetrisWidth; x++)
148 | {
149 | grid[y][x] = grid[y - 1][x];
150 | }
151 | }
152 |
153 | // Set the top row to empty
154 | for (int x = 0; x < tetrisWidth; x++)
155 | {
156 | grid[0][x] = 0;
157 | }
158 |
159 | // Since we moved the rows down, we need to check the same row again
160 | row++;
161 | }
162 | }
163 | }
164 |
165 | // Initialize a new tetromino at the top of the grid
166 | void spawnTetromino()
167 | {
168 | int shapeIndex = esp_random() % 7; // Random index for shape
169 | memcpy(currentTetromino.shape, tetrominoes[shapeIndex], sizeof(currentTetromino.shape));
170 | currentTetromino.x = 0; // Start from the left side (which is now the top)
171 |
172 | // Choose a random y position within the grid's width
173 | // Subtract 4 to ensure the entire tetromino shape fits within the grid
174 | currentTetromino.y = esp_random() % (tetrisHeight - 4);
175 |
176 | currentTetromino.color = tetrominoColors[shapeIndex];
177 | }
178 |
179 | // Check if the tetromino can be placed at a position in the grid
180 | bool canPlace(int x, int y, int shape[4][4])
181 | {
182 | for (int i = 0; i < 4; i++)
183 | {
184 | for (int j = 0; j < 4; j++)
185 | {
186 | if (shape[i][j])
187 | {
188 | int newX = x + j; // newX represents vertical movement in the rotated grid
189 | int newY = y + i; // newY represents horizontal movement
190 |
191 | // Check for out-of-bounds or collision with existing blocks
192 | if (newX < 0 || newX >= tetrisWidth || newY < 0 || newY >= tetrisHeight || grid[newX][newY])
193 | {
194 | return false;
195 | }
196 | }
197 | }
198 | }
199 | return true;
200 | }
201 |
202 | // Place the tetromino on the grid
203 | void placeTetromino()
204 | {
205 | for (int i = 0; i < 4; i++)
206 | {
207 | for (int j = 0; j < 4; j++)
208 | {
209 | if (currentTetromino.shape[i][j])
210 | {
211 | int newX = currentTetromino.x + j;
212 | int newY = currentTetromino.y + i;
213 |
214 | if (newX >= 0 && newX < tetrisWidth && newY >= 0 && newY < tetrisHeight)
215 | {
216 | grid[newX][newY] = currentTetromino.color;
217 | updateGrid[newX][newY] = true; // Mark this cell for updating
218 | }
219 | }
220 | }
221 | }
222 | }
223 |
224 | void clearTetrominoPosition()
225 | {
226 | for (int i = 0; i < 4; i++)
227 | {
228 | for (int j = 0; j < 4; j++)
229 | {
230 | if (currentTetromino.shape[i][j])
231 | {
232 | int newX = currentTetromino.x + j;
233 | int newY = currentTetromino.y + i;
234 |
235 | if (newX >= 0 && newX < tetrisWidth && newY >= 0 && newY < tetrisHeight)
236 | {
237 | grid[newX][newY] = 0; // Clear the cell
238 | updateGrid[newX][newY] = true; // Mark this cell for updating
239 | }
240 | }
241 | }
242 | }
243 | }
244 |
245 | void setupTetris()
246 | {
247 | tetrisWidth = tft->width() / blockSize;
248 | tetrisHeight = tft->height() / blockSize;
249 | grid = std::vector>(tetrisWidth, std::vector(tetrisHeight, 0));
250 | updateGrid = std::vector>(tetrisWidth, std::vector(tetrisHeight, true)); // Initially, all cells need to be drawn
251 |
252 | spawnTetromino();
253 | }
254 |
255 | // Modify drawGrid to only redraw cells that have changed
256 | void drawGrid()
257 | {
258 | for (int x = 0; x < tetrisWidth; x++)
259 | {
260 | for (int y = 0; y < tetrisHeight; y++)
261 | {
262 | if (updateGrid[x][y]) // Only update cells marked for redraw
263 | {
264 | int drawX = x * blockSize;
265 | int drawY = y * blockSize;
266 | uint16_t color = grid[x][y] ? grid[x][y] : TFT_BLACK;
267 | tft->fillRect(drawX, drawY, blockSize, blockSize, color);
268 |
269 | if (!grid[x][y]) // Optionally, redraw the grid lines for empty cells
270 | {
271 | tft->drawRect(drawX, drawY, blockSize, blockSize, 0x4a89);
272 | }
273 |
274 | updateGrid[x][y] = false; // Reset the update flag
275 | }
276 | }
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/font_test.h:
--------------------------------------------------------------------------------
1 | #include "virtualScreen.h"
2 | #include "fonts/Starjedi32pt7b.h"
3 | #include "fonts/raidercrusader48pt7b.h"
4 | #include "fonts/Star_Trek_Enterprise_Future80pt7b.h"
5 |
6 | void printCenteredText(VirtualDisplay *tft, const String &text, const GFXfont *font, uint16_t color)
7 | {
8 |
9 | tft->setFont(font);
10 | tft->setTextColor(color);
11 |
12 | int16_t x1, y1;
13 | uint16_t w, h;
14 | tft->getTextBounds(text, 0, 0, &x1, &y1, &w, &h); // Calculate the bounds of the text
15 |
16 | int x = (tft->width() - w) / 2; // Calculate the x position to center the text
17 | int y = (tft->height() + h) / 2; // Center vertically
18 |
19 | tft->setCursor(x, y);
20 | tft->println(text);
21 | }
22 |
23 | void font_test(VirtualDisplay *tft)
24 | {
25 | tft->fillScreen(TFT_BLACK);
26 | tft->drawRect(10, 20, tft->width() - 50, tft->height() - 50, TFT_GREEN);
27 | tft->drawRect(12, 23, tft->width() - 48, tft->height() - 48, TFT_GREEN);
28 | tft->drawRoundRect(20, 50, tft->width() - 80, tft->height() - 100, 20, TFT_CYAN);
29 | printCenteredText(tft, "Star Wars Yoda Jedi", &Starjedi32pt7b, 0x00ff0c);
30 | tft->output();
31 | delay(5000);
32 | tft->fillScreen(TFT_BLACK);
33 | printCenteredText(tft, "We are Crusaders!", &raidercrusader48pt7b, 0x17bb);
34 | tft->output();
35 | delay(5000);
36 | tft->fillScreen(TFT_BLACK);
37 | printCenteredText(tft, "Star Trek Kirk", &Star_Trek_Enterprise_Future80pt7b, 0x3728);
38 | tft->output();
39 | }
--------------------------------------------------------------------------------
/fonts/BebasNeue_Regular13pt7b.h:
--------------------------------------------------------------------------------
1 | const uint8_t BebasNeue_Regular13pt7bBitmaps[] PROGMEM = {
2 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xB6, 0x07, 0xFC, 0xEF, 0xDB, 0xB6, 0x6C,
3 | 0xC9, 0x80, 0x19, 0x86, 0x61, 0x98, 0x66, 0x7F, 0xDF, 0xF3, 0xB8, 0xCC,
4 | 0x33, 0x0C, 0xC7, 0xF9, 0xFE, 0xFF, 0x8C, 0xC7, 0x71, 0xDC, 0x67, 0x19,
5 | 0x80, 0x18, 0x18, 0x7E, 0xFF, 0xE7, 0xE3, 0xE0, 0xF0, 0x78, 0x3C, 0x1E,
6 | 0x0F, 0x07, 0xE7, 0xE7, 0xE7, 0xFF, 0x7E, 0x18, 0x18, 0x70, 0x67, 0xC6,
7 | 0x36, 0x31, 0xB1, 0x8D, 0x98, 0x6C, 0xC3, 0x64, 0x1B, 0x60, 0xFB, 0x73,
8 | 0xB7, 0xC1, 0xB6, 0x09, 0x30, 0xC9, 0x86, 0x4C, 0x62, 0x63, 0x1B, 0x18,
9 | 0xF9, 0x83, 0x80, 0x3E, 0x3F, 0x3F, 0x9C, 0x0E, 0x07, 0x1B, 0x8C, 0xFF,
10 | 0x3F, 0xBF, 0xF8, 0xDC, 0x6E, 0x37, 0x1B, 0x9D, 0xFE, 0xFF, 0x3D, 0xC0,
11 | 0xFF, 0xEC, 0x80, 0x1B, 0xDF, 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x73,
12 | 0x9C, 0xE7, 0x3E, 0xF3, 0x80, 0x87, 0xBC, 0x73, 0x9C, 0xE7, 0x39, 0xCE,
13 | 0x73, 0x9C, 0xE7, 0x39, 0xFF, 0xEE, 0x00, 0x0E, 0x03, 0x04, 0x45, 0xD7,
14 | 0xFF, 0xC3, 0x81, 0xB0, 0xEE, 0x31, 0x80, 0x18, 0x0C, 0x06, 0x1F, 0xFF,
15 | 0xFF, 0xFC, 0x60, 0x30, 0x18, 0x00, 0xFF, 0xAD, 0x80, 0xFF, 0xFE, 0xFF,
16 | 0x80, 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x07, 0x01, 0xC0, 0x60, 0x38, 0x0C,
17 | 0x03, 0x01, 0xC0, 0x60, 0x38, 0x0C, 0x03, 0x01, 0xC0, 0x60, 0x38, 0x00,
18 | 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
19 | 0xE3, 0xE3, 0xE7, 0xFF, 0x7F, 0x3C, 0x0C, 0x7F, 0xFF, 0xFC, 0x71, 0xC7,
20 | 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x70, 0x3C, 0x7F, 0xFF, 0xE7,
21 | 0xE3, 0xE7, 0x07, 0x07, 0x0E, 0x1C, 0x3C, 0x78, 0x70, 0xE0, 0xE0, 0xFF,
22 | 0xFF, 0xFF, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7, 0x07, 0x07, 0x1F, 0x1C, 0x1E,
23 | 0x07, 0x07, 0xC7, 0xC7, 0xE7, 0xFF, 0x7E, 0x3C, 0x07, 0x81, 0xE0, 0xF8,
24 | 0x3E, 0x0F, 0x87, 0xE1, 0xB8, 0xEE, 0x33, 0x9C, 0xE7, 0x39, 0x8E, 0xFF,
25 | 0xFF, 0xFF, 0xFC, 0x0E, 0x03, 0x80, 0xE0, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0,
26 | 0xE4, 0xFF, 0xFF, 0xE7, 0xE7, 0x03, 0x03, 0xE3, 0xE3, 0xE7, 0xFF, 0x7F,
27 | 0x3C, 0x3C, 0x7F, 0xFF, 0xE3, 0xE3, 0xE0, 0xE4, 0xFF, 0xFF, 0xE7, 0xE3,
28 | 0xE3, 0xE3, 0xE3, 0xE3, 0xFF, 0x7F, 0x3E, 0xFF, 0xFF, 0xFF, 0x07, 0x07,
29 | 0x06, 0x0E, 0x0E, 0x0E, 0x1C, 0x1C, 0x1C, 0x18, 0x38, 0x38, 0x38, 0x70,
30 | 0x70, 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E, 0xFF, 0xE7,
31 | 0xE3, 0xE3, 0xE3, 0xE3, 0xFF, 0xFF, 0x3E, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7,
32 | 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, 0x7F, 0x27, 0x07, 0xC7, 0xE7, 0xFF, 0x7E,
33 | 0x3C, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0xB4,
34 | 0x03, 0x0F, 0x3C, 0xF0, 0xE0, 0x7C, 0x1F, 0x03, 0xFF, 0xFF, 0xFF, 0x00,
35 | 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3E, 0x0F, 0x07, 0x3E, 0xF8, 0xC0, 0x3E,
36 | 0x3F, 0x9F, 0xCC, 0x7E, 0x3F, 0x1C, 0x0C, 0x0E, 0x0E, 0x07, 0x07, 0x03,
37 | 0x81, 0x80, 0x00, 0x00, 0x38, 0x1C, 0x0E, 0x00, 0x00, 0x40, 0x07, 0xF8,
38 | 0x1F, 0xFC, 0x3C, 0x1E, 0x38, 0x07, 0x71, 0x37, 0x67, 0xB3, 0xE7, 0xF3,
39 | 0xC6, 0x73, 0xCE, 0x73, 0xCE, 0x73, 0xCE, 0x73, 0xCE, 0x76, 0xCE, 0xFE,
40 | 0xCF, 0xFC, 0xE7, 0x78, 0xE0, 0x00, 0x70, 0x08, 0x3F, 0xF8, 0x1F, 0xF8,
41 | 0x07, 0xE0, 0x1E, 0x07, 0x81, 0xE0, 0x7C, 0x3F, 0x0F, 0xC3, 0xF0, 0xCC,
42 | 0x33, 0x0C, 0xE7, 0x39, 0xCE, 0x7F, 0x9F, 0xE6, 0x19, 0x87, 0x61, 0xF8,
43 | 0x70, 0xFE, 0x7F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x9D, 0xFE, 0xFE, 0x7F,
44 | 0xB9, 0xDC, 0x7E, 0x3F, 0x1F, 0x8F, 0xFE, 0xFF, 0x7F, 0x00, 0x3C, 0x7E,
45 | 0xFF, 0xE7, 0xE7, 0xE7, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7,
46 | 0xE7, 0xFF, 0x7E, 0x3C, 0xFE, 0x7F, 0xBF, 0xDC, 0x6E, 0x3F, 0x1F, 0x8F,
47 | 0xC7, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8D, 0xFE, 0xFF, 0x7F,
48 | 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0,
49 | 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x1C,
50 | 0x38, 0x7E, 0xFD, 0xFB, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x3C,
51 | 0x7E, 0xFF, 0xE7, 0xE3, 0xE3, 0xE0, 0xE0, 0xEF, 0xEF, 0xEF, 0xE3, 0xE3,
52 | 0xE3, 0xE7, 0xFF, 0x7E, 0x3C, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F,
53 | 0x8F, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3,
54 | 0xF1, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1C, 0x71, 0xC7,
55 | 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xFF, 0xFB, 0xC0, 0xE3,
56 | 0xF1, 0xB9, 0xDC, 0xCE, 0xE7, 0x73, 0xF1, 0xF8, 0xFC, 0x7F, 0x3F, 0x9D,
57 | 0xCE, 0x77, 0x3B, 0x9D, 0xC7, 0xE3, 0xF1, 0xC0, 0xE1, 0xC3, 0x87, 0x0E,
58 | 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x7F, 0xFF, 0xFC,
59 | 0xF0, 0xFF, 0x1F, 0xF1, 0xFF, 0x9F, 0xF9, 0xFD, 0x9F, 0xD9, 0xFD, 0x9F,
60 | 0xDB, 0x7D, 0xB7, 0xDB, 0x7C, 0xF7, 0xCF, 0x7C, 0xF7, 0xCE, 0x7C, 0xE7,
61 | 0xCE, 0x7C, 0xE7, 0xF3, 0xF9, 0xFC, 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7,
62 | 0xFF, 0xF7, 0xFB, 0xFD, 0xFE, 0x7F, 0x3F, 0x9F, 0xCF, 0xE3, 0xF1, 0xC0,
63 | 0x3C, 0x7F, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
64 | 0xE3, 0xE3, 0xE7, 0xFF, 0x7F, 0x3C, 0xFC, 0xFF, 0xFF, 0xE7, 0xE3, 0xE3,
65 | 0xE3, 0xE7, 0xFF, 0xFE, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
66 | 0x3C, 0x3F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0xB8,
67 | 0xDC, 0x6E, 0x37, 0x1B, 0x9D, 0xFE, 0x7F, 0x1F, 0xC0, 0xE0, 0x10, 0xFE,
68 | 0x7F, 0xBF, 0xDC, 0xEE, 0x37, 0x1B, 0x8D, 0xCE, 0xFE, 0x7F, 0x3F, 0xDC,
69 | 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0x80, 0x3C, 0xFE, 0xFF, 0xC7,
70 | 0xC7, 0xE0, 0xE0, 0x70, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0xC7, 0xFF,
71 | 0xFE, 0x7C, 0xFF, 0xFF, 0xFF, 0xE3, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C,
72 | 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x00, 0xE3,
73 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
74 | 0xE3, 0xE7, 0xFF, 0x7E, 0x3C, 0xE1, 0xB0, 0xD8, 0xEE, 0x77, 0x3B, 0x9D,
75 | 0xCC, 0xE6, 0x33, 0x19, 0x8F, 0xC7, 0xE3, 0xF1, 0xF0, 0xF8, 0x3C, 0x1E,
76 | 0x0F, 0x00, 0xE3, 0x9D, 0x8E, 0x76, 0x79, 0xD9, 0xE6, 0x67, 0x99, 0xDE,
77 | 0x67, 0x79, 0x9D, 0xE6, 0x76, 0xD9, 0xDB, 0x67, 0x6F, 0x8D, 0xBE, 0x3E,
78 | 0xF8, 0xF3, 0xC3, 0xCF, 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC0, 0xF1, 0xDC,
79 | 0x67, 0x38, 0xCE, 0x3B, 0x0F, 0xC1, 0xF0, 0x78, 0x1E, 0x07, 0x81, 0xE0,
80 | 0x7C, 0x3F, 0x0C, 0xC7, 0x39, 0xCE, 0x61, 0xF8, 0x70, 0xE1, 0xDC, 0x67,
81 | 0x39, 0xCE, 0x33, 0x0E, 0xC3, 0xF0, 0x78, 0x1E, 0x07, 0x80, 0xC0, 0x30,
82 | 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0x7F, 0xBF, 0xDF, 0xE0,
83 | 0xE0, 0x70, 0x70, 0x38, 0x1C, 0x1C, 0x0E, 0x0E, 0x07, 0x03, 0x83, 0x81,
84 | 0xC1, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xCE, 0x73, 0x9C, 0xE7, 0x39,
85 | 0xCE, 0x73, 0x9C, 0xE7, 0x3F, 0xFF, 0x80, 0xE0, 0x18, 0x07, 0x00, 0xC0,
86 | 0x30, 0x0E, 0x01, 0x80, 0x70, 0x0C, 0x03, 0x00, 0xE0, 0x18, 0x07, 0x00,
87 | 0xC0, 0x30, 0x0E, 0x01, 0x80, 0x70, 0xFF, 0xFE, 0x73, 0x9C, 0xE7, 0x39,
88 | 0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xFF, 0xFF, 0x80, 0x0C, 0x07, 0x81, 0xE0,
89 | 0xEC, 0x33, 0x1C, 0x6E, 0x1C, 0xFF, 0xFF, 0xFF, 0xE3, 0x8E, 0x1E, 0x07,
90 | 0x81, 0xE0, 0x7C, 0x3F, 0x0F, 0xC3, 0xF0, 0xCC, 0x33, 0x0C, 0xE7, 0x39,
91 | 0xCE, 0x7F, 0x9F, 0xE6, 0x19, 0x87, 0x61, 0xF8, 0x70, 0xFE, 0x7F, 0xBF,
92 | 0xDC, 0xEE, 0x37, 0x1B, 0x9D, 0xFE, 0xFE, 0x7F, 0xB9, 0xDC, 0x7E, 0x3F,
93 | 0x1F, 0x8F, 0xFE, 0xFF, 0x7F, 0x00, 0x3C, 0x7E, 0xFF, 0xE7, 0xE7, 0xE7,
94 | 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF, 0x7E, 0x3C,
95 | 0xFE, 0x7F, 0xBF, 0xDC, 0x6E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xF8,
96 | 0xFC, 0x7E, 0x3F, 0x1F, 0x8D, 0xFE, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF,
97 | 0xE0, 0xE0, 0xE0, 0xE0, 0xFE, 0xFE, 0xFE, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
98 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x1C, 0x38, 0x7E, 0xFD, 0xFB,
99 | 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC0, 0x3C, 0x7E, 0xFF, 0xE7, 0xE3,
100 | 0xE3, 0xE0, 0xE0, 0xEF, 0xEF, 0xEF, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E,
101 | 0x3C, 0xE3, 0xF1, 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xFF, 0xFF, 0xFF,
102 | 0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8F, 0xC7, 0xE3, 0xF1, 0xC0, 0xFF, 0xFF,
103 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
104 | 0x71, 0xC7, 0x1C, 0x71, 0xFF, 0xFB, 0xC0, 0xE3, 0xF1, 0xB9, 0xDC, 0xCE,
105 | 0xE7, 0x73, 0xF1, 0xF8, 0xFC, 0x7F, 0x3F, 0x9D, 0xCE, 0x77, 0x3B, 0x9D,
106 | 0xC7, 0xE3, 0xF1, 0xC0, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1,
107 | 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x7F, 0xFF, 0xFC, 0xF0, 0xFF, 0x1F, 0xF1,
108 | 0xFF, 0x9F, 0xF9, 0xFD, 0x9F, 0xD9, 0xFD, 0x9F, 0xDB, 0x7D, 0xB7, 0xDB,
109 | 0x7C, 0xF7, 0xCF, 0x7C, 0xF7, 0xCE, 0x7C, 0xE7, 0xCE, 0x7C, 0xE7, 0xF3,
110 | 0xF9, 0xFC, 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFF, 0xF7, 0xFB, 0xFD,
111 | 0xFE, 0x7F, 0x3F, 0x9F, 0xCF, 0xE3, 0xF1, 0xC0, 0x3C, 0x7F, 0xFF, 0xE7,
112 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF,
113 | 0x7F, 0x3C, 0xFC, 0xFF, 0xFF, 0xE7, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0xFE,
114 | 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x3C, 0x3F, 0xBF, 0xDC,
115 | 0xEE, 0x37, 0x1B, 0x8D, 0xC6, 0xE3, 0x71, 0xB8, 0xDC, 0x6E, 0x37, 0x1B,
116 | 0x9D, 0xFE, 0x7F, 0x1F, 0xC0, 0xE0, 0x10, 0xFE, 0x7F, 0xBF, 0xDC, 0xEE,
117 | 0x37, 0x1B, 0x8D, 0xCE, 0xFE, 0x7F, 0x3F, 0xDC, 0xEE, 0x37, 0x1B, 0x8D,
118 | 0xC6, 0xE3, 0x71, 0x80, 0x3C, 0xFE, 0xFF, 0xC7, 0xC7, 0xE0, 0xE0, 0x70,
119 | 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0xC7, 0xFF, 0xFE, 0x7C, 0xFF, 0xFF,
120 | 0xFF, 0xE3, 0x81, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81,
121 | 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x00, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
122 | 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE7, 0xFF, 0x7E,
123 | 0x3C, 0xE1, 0xB0, 0xD8, 0xEE, 0x77, 0x3B, 0x9D, 0xCC, 0xE6, 0x33, 0x19,
124 | 0x8F, 0xC7, 0xE3, 0xF1, 0xF0, 0xF8, 0x3C, 0x1E, 0x0F, 0x00, 0xE3, 0x9D,
125 | 0x8E, 0x76, 0x79, 0xD9, 0xE6, 0x67, 0x99, 0xDE, 0x67, 0x79, 0x9D, 0xE6,
126 | 0x76, 0xD9, 0xDB, 0x67, 0x6F, 0x8D, 0xBE, 0x3E, 0xF8, 0xF3, 0xC3, 0xCF,
127 | 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC0, 0xF1, 0xDC, 0x67, 0x38, 0xCE, 0x3B,
128 | 0x0F, 0xC1, 0xF0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x7C, 0x3F, 0x0C, 0xC7,
129 | 0x39, 0xCE, 0x61, 0xF8, 0x70, 0xE1, 0xDC, 0x67, 0x39, 0xCE, 0x33, 0x0E,
130 | 0xC3, 0xF0, 0x78, 0x1E, 0x07, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0,
131 | 0x30, 0x0C, 0x03, 0x00, 0x7F, 0xBF, 0xDF, 0xE0, 0xE0, 0x70, 0x70, 0x38,
132 | 0x1C, 0x1C, 0x0E, 0x0E, 0x07, 0x03, 0x83, 0x81, 0xC1, 0xFF, 0xFF, 0xFF,
133 | 0xC0, 0x19, 0xDE, 0xE7, 0x39, 0xCE, 0x77, 0x39, 0xC7, 0x39, 0xCE, 0x73,
134 | 0x9E, 0xF3, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
135 | 0xE0, 0x87, 0x3C, 0xE7, 0x39, 0xCE, 0x71, 0xCE, 0x77, 0x39, 0xCE, 0x73,
136 | 0xBD, 0xEE, 0x00, 0x10, 0x9F, 0xFF, 0xF9, 0x1C };
137 |
138 | const GFXglyph BebasNeue_Regular13pt7bGlyphs[] PROGMEM = {
139 | { 0, 1, 1, 4, 0, 0 }, // 0x20 ' '
140 | { 1, 3, 18, 5, 1, -17 }, // 0x21 '!'
141 | { 8, 7, 6, 9, 1, -17 }, // 0x22 '"'
142 | { 14, 10, 18, 10, 0, -17 }, // 0x23 '#'
143 | { 37, 8, 20, 10, 1, -18 }, // 0x24 '$'
144 | { 57, 13, 18, 15, 1, -17 }, // 0x25 '%'
145 | { 87, 9, 18, 11, 1, -17 }, // 0x26 '&'
146 | { 108, 3, 6, 5, 1, -17 }, // 0x27 '''
147 | { 111, 5, 21, 7, 1, -19 }, // 0x28 '('
148 | { 125, 5, 21, 7, 1, -19 }, // 0x29 ')'
149 | { 139, 10, 9, 11, 0, -17 }, // 0x2A '*'
150 | { 151, 9, 9, 10, 1, -12 }, // 0x2B '+'
151 | { 162, 3, 6, 5, 1, -2 }, // 0x2C ','
152 | { 165, 5, 3, 7, 1, -10 }, // 0x2D '-'
153 | { 167, 3, 3, 5, 1, -2 }, // 0x2E '.'
154 | { 169, 10, 18, 10, 0, -17 }, // 0x2F '/'
155 | { 192, 8, 18, 10, 1, -17 }, // 0x30 '0'
156 | { 210, 6, 18, 10, 2, -17 }, // 0x31 '1'
157 | { 224, 8, 18, 10, 1, -17 }, // 0x32 '2'
158 | { 242, 8, 18, 10, 1, -17 }, // 0x33 '3'
159 | { 260, 10, 18, 10, 0, -17 }, // 0x34 '4'
160 | { 283, 8, 18, 10, 1, -17 }, // 0x35 '5'
161 | { 301, 8, 18, 10, 1, -17 }, // 0x36 '6'
162 | { 319, 8, 18, 10, 1, -17 }, // 0x37 '7'
163 | { 337, 8, 18, 10, 1, -17 }, // 0x38 '8'
164 | { 355, 8, 18, 10, 1, -17 }, // 0x39 '9'
165 | { 373, 3, 13, 5, 1, -12 }, // 0x3A ':'
166 | { 378, 3, 16, 5, 1, -12 }, // 0x3B ';'
167 | { 384, 8, 8, 10, 1, -12 }, // 0x3C '<'
168 | { 392, 8, 7, 10, 1, -12 }, // 0x3D '='
169 | { 399, 8, 8, 10, 1, -12 }, // 0x3E '>'
170 | { 407, 9, 18, 9, 0, -17 }, // 0x3F '?'
171 | { 428, 16, 21, 18, 1, -18 }, // 0x40 '@'
172 | { 470, 10, 18, 10, 0, -17 }, // 0x41 'A'
173 | { 493, 9, 18, 10, 1, -17 }, // 0x42 'B'
174 | { 514, 8, 18, 10, 1, -17 }, // 0x43 'C'
175 | { 532, 9, 18, 10, 1, -17 }, // 0x44 'D'
176 | { 553, 8, 18, 9, 1, -17 }, // 0x45 'E'
177 | { 571, 7, 18, 9, 1, -17 }, // 0x46 'F'
178 | { 587, 8, 18, 10, 1, -17 }, // 0x47 'G'
179 | { 605, 9, 18, 11, 1, -17 }, // 0x48 'H'
180 | { 626, 3, 18, 5, 1, -17 }, // 0x49 'I'
181 | { 633, 6, 18, 7, 0, -17 }, // 0x4A 'J'
182 | { 647, 9, 18, 11, 1, -17 }, // 0x4B 'K'
183 | { 668, 7, 18, 9, 1, -17 }, // 0x4C 'L'
184 | { 684, 12, 18, 14, 1, -17 }, // 0x4D 'M'
185 | { 711, 9, 18, 11, 1, -17 }, // 0x4E 'N'
186 | { 732, 8, 18, 10, 1, -17 }, // 0x4F 'O'
187 | { 750, 8, 18, 10, 1, -17 }, // 0x50 'P'
188 | { 768, 9, 20, 10, 1, -17 }, // 0x51 'Q'
189 | { 791, 9, 18, 10, 1, -17 }, // 0x52 'R'
190 | { 812, 8, 18, 9, 1, -17 }, // 0x53 'S'
191 | { 830, 9, 18, 9, 0, -17 }, // 0x54 'T'
192 | { 851, 8, 18, 10, 1, -17 }, // 0x55 'U'
193 | { 869, 9, 18, 10, 0, -17 }, // 0x56 'V'
194 | { 890, 14, 18, 14, 0, -17 }, // 0x57 'W'
195 | { 922, 10, 18, 10, 0, -17 }, // 0x58 'X'
196 | { 945, 10, 18, 10, 0, -17 }, // 0x59 'Y'
197 | { 968, 9, 18, 9, 0, -17 }, // 0x5A 'Z'
198 | { 989, 5, 21, 7, 1, -19 }, // 0x5B '['
199 | { 1003, 10, 18, 10, 0, -17 }, // 0x5C '\'
200 | { 1026, 5, 21, 7, 1, -19 }, // 0x5D ']'
201 | { 1040, 10, 7, 10, 0, -17 }, // 0x5E '^'
202 | { 1049, 8, 3, 8, 0, 0 }, // 0x5F '_'
203 | { 1052, 5, 3, 13, 3, -21 }, // 0x60 '`'
204 | { 1054, 10, 18, 10, 0, -17 }, // 0x61 'a'
205 | { 1077, 9, 18, 10, 1, -17 }, // 0x62 'b'
206 | { 1098, 8, 18, 10, 1, -17 }, // 0x63 'c'
207 | { 1116, 9, 18, 10, 1, -17 }, // 0x64 'd'
208 | { 1137, 8, 18, 9, 1, -17 }, // 0x65 'e'
209 | { 1155, 7, 18, 9, 1, -17 }, // 0x66 'f'
210 | { 1171, 8, 18, 10, 1, -17 }, // 0x67 'g'
211 | { 1189, 9, 18, 11, 1, -17 }, // 0x68 'h'
212 | { 1210, 3, 18, 5, 1, -17 }, // 0x69 'i'
213 | { 1217, 6, 18, 7, 0, -17 }, // 0x6A 'j'
214 | { 1231, 9, 18, 11, 1, -17 }, // 0x6B 'k'
215 | { 1252, 7, 18, 9, 1, -17 }, // 0x6C 'l'
216 | { 1268, 12, 18, 14, 1, -17 }, // 0x6D 'm'
217 | { 1295, 9, 18, 11, 1, -17 }, // 0x6E 'n'
218 | { 1316, 8, 18, 10, 1, -17 }, // 0x6F 'o'
219 | { 1334, 8, 18, 10, 1, -17 }, // 0x70 'p'
220 | { 1352, 9, 20, 10, 1, -17 }, // 0x71 'q'
221 | { 1375, 9, 18, 10, 1, -17 }, // 0x72 'r'
222 | { 1396, 8, 18, 9, 1, -17 }, // 0x73 's'
223 | { 1414, 9, 18, 9, 0, -17 }, // 0x74 't'
224 | { 1435, 8, 18, 10, 1, -17 }, // 0x75 'u'
225 | { 1453, 9, 18, 10, 0, -17 }, // 0x76 'v'
226 | { 1474, 14, 18, 14, 0, -17 }, // 0x77 'w'
227 | { 1506, 10, 18, 10, 0, -17 }, // 0x78 'x'
228 | { 1529, 10, 18, 10, 0, -17 }, // 0x79 'y'
229 | { 1552, 9, 18, 9, 0, -17 }, // 0x7A 'z'
230 | { 1573, 5, 21, 7, 1, -19 }, // 0x7B '{'
231 | { 1587, 3, 25, 13, 5, -19 }, // 0x7C '|'
232 | { 1597, 5, 21, 7, 1, -19 }, // 0x7D '}'
233 | { 1611, 10, 4, 10, 0, -10 } }; // 0x7E '~'
234 |
235 | const GFXfont BebasNeue_Regular13pt7b PROGMEM = {
236 | (uint8_t *)BebasNeue_Regular13pt7bBitmaps,
237 | (GFXglyph *)BebasNeue_Regular13pt7bGlyphs,
238 | 0x20, 0x7E, 31 };
239 |
240 | // Approx. 2288 bytes
241 |
--------------------------------------------------------------------------------
/fonts/Fun_Games20pt7b.h:
--------------------------------------------------------------------------------
1 | const uint8_t Fun_Games20pt7bBitmaps[] PROGMEM = {
2 | 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x38,
3 | 0xC2, 0x10, 0x7F, 0xFF, 0xFF, 0xC0, 0xEF, 0xDF, 0xBF, 0x7E, 0xFD, 0xFB,
4 | 0x80, 0x01, 0x80, 0x80, 0x03, 0x83, 0xC0, 0x1E, 0x0E, 0x00, 0x70, 0x38,
5 | 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80, 0x1C, 0x1E, 0x1F, 0xFF, 0xFF, 0x7F,
6 | 0xFF, 0xFD, 0xFF, 0xFF, 0xF0, 0x38, 0x1C, 0x00, 0xE0, 0xF0, 0x03, 0x83,
7 | 0x80, 0x1E, 0x0E, 0x00, 0x78, 0x38, 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80,
8 | 0x1C, 0x1E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x38,
9 | 0x1C, 0x00, 0xE0, 0x70, 0x03, 0x83, 0xC0, 0x0E, 0x0E, 0x00, 0x78, 0x38,
10 | 0x01, 0xC0, 0xE0, 0x07, 0x03, 0x80, 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00,
11 | 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0x01, 0xFF, 0xFE, 0x03, 0xFF, 0xFC,
12 | 0x07, 0xFF, 0xF8, 0x07, 0xFF, 0xF0, 0x0F, 0xFF, 0xF0, 0x0F, 0x80, 0x00,
13 | 0x1F, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7F, 0xFF, 0xFF,
14 | 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF,
15 | 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
16 | 0x00, 0x00, 0xF8, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0,
17 | 0x3F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0x80, 0x0F, 0x00, 0x00, 0x0F, 0x00,
18 | 0x00, 0x0F, 0x00, 0x00, 0x0F, 0x00, 0xFC, 0x1F, 0xF8, 0x3B, 0xF0, 0xF7,
19 | 0xE1, 0xEF, 0xC7, 0x9F, 0x8F, 0x00, 0x3C, 0x00, 0x78, 0x01, 0xE0, 0x03,
20 | 0xC0, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x80,
21 | 0x1E, 0x00, 0x3C, 0x00, 0x7B, 0xF1, 0xE7, 0xE3, 0xCF, 0xCF, 0x1F, 0x9E,
22 | 0x3F, 0x78, 0x7E, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F,
23 | 0xFF, 0xF8, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00,
24 | 0x00, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
25 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3E, 0x3E, 0x00, 0xF8, 0xF8,
26 | 0x03, 0xE3, 0xE0, 0x0F, 0x8F, 0xC0, 0x3E, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF,
27 | 0xE0, 0xFF, 0xFF, 0x81, 0xFF, 0xFE, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8,
28 | 0x07, 0xFF, 0x0F, 0xFE, 0x3F, 0xFC, 0x7F, 0xF0, 0xFF, 0xE0, 0xFC, 0x00,
29 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
30 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
31 | 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8, 0x00,
32 | 0xFC, 0x00, 0xFF, 0xE0, 0x7F, 0xF0, 0x3F, 0xFC, 0x0F, 0xFE, 0x07, 0xFF,
33 | 0xFF, 0xE0, 0x7F, 0xF0, 0x1F, 0xFC, 0x0F, 0xFE, 0x07, 0xFF, 0x00, 0x3F,
34 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
35 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
36 | 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F,
37 | 0x00, 0x3F, 0x07, 0xFF, 0x0F, 0xFE, 0x1F, 0xFC, 0x7F, 0xF0, 0xFF, 0xE0,
38 | 0x0C, 0x0B, 0x47, 0xF8, 0xFC, 0xFF, 0xFF, 0xF3, 0xF1, 0xFE, 0x2D, 0x03,
39 | 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0, 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00,
40 | 0x0F, 0x80, 0x00, 0x7C, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0x00, 0xFF, 0xFF,
41 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
42 | 0x7C, 0x00, 0x03, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0,
43 | 0x00, 0x3E, 0x00, 0x01, 0xF0, 0x00, 0x0F, 0x80, 0x00, 0xFF, 0xFF, 0xFF,
44 | 0xFB, 0xDC, 0xC4, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
45 | 0x80, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x18, 0x00, 0x70, 0x03, 0xC0, 0x0E,
46 | 0x00, 0x78, 0x01, 0xC0, 0x07, 0x00, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x1C,
47 | 0x00, 0xF0, 0x03, 0x80, 0x0E, 0x00, 0x78, 0x01, 0xC0, 0x0F, 0x00, 0x38,
48 | 0x01, 0xE0, 0x07, 0x00, 0x1C, 0x00, 0xF0, 0x03, 0x80, 0x1E, 0x00, 0x70,
49 | 0x01, 0xC0, 0x0F, 0x00, 0x38, 0x00, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
50 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F,
51 | 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00,
52 | 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF,
53 | 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF,
54 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
55 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0,
56 | 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xF0, 0x7C, 0x1F,
57 | 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC0, 0xF0, 0x1C, 0x03, 0x00, 0xC0,
58 | 0x10, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
59 | 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
60 | 0x00, 0x00, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF,
61 | 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBE, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C,
62 | 0x00, 0x00, 0xFC, 0x00, 0x00, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x01, 0xFF,
63 | 0xFF, 0x01, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,
64 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07,
65 | 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
66 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
67 | 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x1F, 0x87, 0xFF, 0xF1, 0xFF, 0xFC,
68 | 0x7F, 0xFF, 0x0F, 0xFF, 0xC3, 0xFF, 0xE0, 0xF8, 0x03, 0xFF, 0x00, 0x7F,
69 | 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF,
70 | 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF,
71 | 0x80, 0x3F, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
72 | 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0,
73 | 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x3C, 0x00, 0x03, 0x80,
74 | 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x40, 0x00, 0x08, 0x07, 0xFF, 0xFE,
75 | 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE1, 0xFF, 0xFF, 0x83, 0xFF, 0xFE, 0x0F,
76 | 0xE0, 0x00, 0x3F, 0x80, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF,
77 | 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xC0, 0x00,
78 | 0x1F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFC, 0x00, 0x03, 0xF0, 0x00, 0x07,
79 | 0xE0, 0x00, 0x0F, 0x80, 0x7F, 0xFF, 0x01, 0xFF, 0xFC, 0x07, 0xFF, 0xF8,
80 | 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF,
81 | 0xFF, 0xF9, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, 0x7C, 0x00, 0x03, 0xE0, 0x00,
82 | 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
83 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
84 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
85 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
86 | 0xFF, 0xF8, 0x7F, 0xFF, 0x0F, 0xFF, 0xE0, 0xFF, 0xF8, 0x00, 0x1F, 0x00,
87 | 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00,
88 | 0x1F, 0x80, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00,
89 | 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01,
90 | 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0x80, 0x01, 0xF0, 0x00, 0x1E, 0x00, 0x03,
91 | 0x80, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xFF,
92 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
93 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
94 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03,
95 | 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF,
96 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
98 | 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF,
99 | 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100 | 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x07, 0xC0,
101 | 0x00, 0x3E, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0x9F, 0xFF, 0xFD, 0xFF, 0xFF,
102 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
103 | 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00,
104 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xDC, 0xC4, 0x20, 0x00, 0x08,
105 | 0x01, 0xC0, 0x3E, 0x03, 0xF0, 0x7F, 0x87, 0xF0, 0xFF, 0x1F, 0xE0, 0xFC,
106 | 0x07, 0xC0, 0x38, 0x01, 0xF0, 0x0F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFC,
107 | 0x07, 0xF8, 0x0F, 0xC0, 0x1E, 0x00, 0x70, 0x00, 0x80, 0xFF, 0xFF, 0xFF,
108 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F,
109 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
110 | 0x80, 0x07, 0x00, 0x3E, 0x01, 0xF8, 0x0F, 0xF0, 0x1F, 0xC0, 0x7F, 0x80,
111 | 0xFF, 0x01, 0xF8, 0x07, 0xC0, 0x0E, 0x01, 0xF0, 0x1F, 0x83, 0xFC, 0x7F,
112 | 0x87, 0xF0, 0xFF, 0x07, 0xE0, 0x3C, 0x01, 0xC0, 0x08, 0x00, 0x00, 0xFF,
113 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
114 | 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x3F, 0xFC, 0x07,
115 | 0xFF, 0x80, 0xFF, 0xF0, 0x1F, 0xFE, 0x03, 0xFF, 0xC0, 0x00, 0x00, 0x00,
116 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x1F,
117 | 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF,
118 | 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x3F, 0xC7, 0xE3,
119 | 0xFC, 0x7E, 0x30, 0xC7, 0xE3, 0x3C, 0x7E, 0x37, 0xC7, 0xE3, 0xEC, 0x7E,
120 | 0x3C, 0xC7, 0xE3, 0x8C, 0x7E, 0x38, 0xC7, 0xE3, 0x00, 0x7E, 0x20, 0x07,
121 | 0xE4, 0x00, 0x7E, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122 | 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123 | 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x03, 0x1F, 0xF8, 0x3C,
124 | 0xFF, 0xC1, 0xF7, 0xFE, 0x1F, 0xFF, 0xF1, 0xFD, 0xFF, 0x9F, 0xCF, 0xFD,
125 | 0xFC, 0x7F, 0xEF, 0xC3, 0xFF, 0xFC, 0x1F, 0xFF, 0xE0, 0xFF, 0xFE, 0x07,
126 | 0xFF, 0xE0, 0x3F, 0xFE, 0x01, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0x7F, 0xF0,
127 | 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0x07, 0x80, 0x00, 0x38, 0x00, 0x01,
128 | 0x80, 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
129 | 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, 0xFF, 0xCF, 0xFF, 0xFC, 0x7C, 0x03, 0xE3,
130 | 0xE0, 0x3E, 0x1F, 0x03, 0xE0, 0xF8, 0x7F, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F,
131 | 0xFF, 0xF0, 0xFF, 0xFF, 0x87, 0xFF, 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xDF,
132 | 0x00, 0xFC, 0xF8, 0x0F, 0xC7, 0xC0, 0xFE, 0x3E, 0x07, 0xE1, 0xF0, 0x7E,
133 | 0x0F, 0x87, 0xE0, 0x7C, 0x7F, 0x03, 0xE3, 0xF0, 0x1F, 0x3F, 0x00, 0x03,
134 | 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xF8, 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00,
135 | 0x03, 0xC0, 0x00, 0x04, 0x00, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F,
136 | 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F,
137 | 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00,
138 | 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x3E, 0xF8, 0x03,
139 | 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF,
140 | 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
141 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0,
142 | 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80,
143 | 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00,
144 | 0x7F, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFF,
145 | 0xC7, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
146 | 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
147 | 0xFC, 0xFF, 0xF0, 0xFF, 0xE0, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
148 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
149 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
150 | 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3F,
151 | 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8, 0xFF, 0xF8, 0x3F, 0xFC, 0x0F, 0x80,
152 | 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00,
153 | 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xF1,
154 | 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00,
155 | 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x1F, 0xFF, 0x83, 0xFF, 0xF8, 0x7F,
156 | 0xFF, 0x8F, 0xFF, 0xF9, 0xFF, 0xFF, 0xA0, 0x1F, 0xF8, 0x01, 0xFF, 0x80,
157 | 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
158 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x08,
159 | 0x00, 0x00, 0x40, 0x00, 0x06, 0x00, 0x00, 0x70, 0x00, 0x07, 0x80, 0x00,
160 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
161 | 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03,
162 | 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
163 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
164 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80,
165 | 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x00, 0x0F, 0x00, 0x00, 0x38, 0x00, 0x00,
166 | 0xC0, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
167 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
168 | 0xDE, 0x71, 0x84, 0x20, 0x7F, 0xFE, 0x7F, 0xFC, 0x7F, 0xF8, 0x7F, 0xF0,
169 | 0x7F, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00,
170 | 0xF8, 0x01, 0xF0, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F,
171 | 0xE0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF, 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC,
172 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xC7, 0xFC, 0x0F, 0xE0, 0x1E, 0x00,
173 | 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x07, 0x00, 0x00, 0x3E, 0x00,
174 | 0x00, 0xFC, 0xF8, 0x07, 0xE3, 0xE0, 0x3F, 0x8F, 0x81, 0xFC, 0x3E, 0x0F,
175 | 0xE0, 0xF8, 0x7F, 0x03, 0xE3, 0xF8, 0x0F, 0x9F, 0xC0, 0x3E, 0xFE, 0x00,
176 | 0xFF, 0xF0, 0x03, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0xFF,
177 | 0xE0, 0x03, 0xFF, 0xC0, 0x0F, 0xFF, 0x80, 0x3F, 0x7F, 0x00, 0xF8, 0xFC,
178 | 0x03, 0xE1, 0xF8, 0x0F, 0x87, 0xF0, 0x3E, 0x0F, 0xC0, 0xF8, 0x1F, 0x83,
179 | 0xE0, 0x7F, 0x0F, 0x80, 0xFC, 0x3E, 0x01, 0xF8, 0xF8, 0x03, 0xF1, 0xE0,
180 | 0x0F, 0xC3, 0x80, 0x1F, 0x86, 0x00, 0x3F, 0x18, 0x00, 0xFC, 0x20, 0x01,
181 | 0xE0, 0x80, 0x02, 0x00, 0x80, 0x00, 0x38, 0x00, 0x0F, 0x80, 0x03, 0xE0,
182 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00,
183 | 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
184 | 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
185 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
186 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70,
187 | 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F,
188 | 0xE0, 0x00, 0x3F, 0xF8, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x3F,
189 | 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x1F,
190 | 0xFF, 0xFF, 0x8F, 0xFF, 0xF7, 0xEF, 0xDF, 0xFB, 0xFF, 0xEF, 0xFC, 0xFF,
191 | 0xE7, 0xFE, 0x3F, 0xE3, 0xFF, 0x0F, 0xE1, 0xFF, 0x87, 0xF0, 0xFF, 0xC1,
192 | 0xF0, 0x7F, 0xE0, 0x70, 0x3F, 0xF0, 0x10, 0x1F, 0xF8, 0x00, 0x0F, 0xFC,
193 | 0x00, 0x07, 0xFE, 0x00, 0x03, 0xE0, 0x80, 0x00, 0x10, 0x00, 0x03, 0x00,
194 | 0x00, 0x70, 0x01, 0xFF, 0x00, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xE0,
195 | 0x1F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F, 0xFE, 0x0F, 0xFF, 0xE1, 0xFF, 0xFE,
196 | 0x3F, 0xFF, 0xE7, 0xFE, 0xFE, 0xFF, 0xCF, 0xDF, 0xF8, 0xFF, 0xFF, 0x0F,
197 | 0xFF, 0xE1, 0xFF, 0xFC, 0x1F, 0xFF, 0x81, 0xFF, 0xF0, 0x1F, 0xFE, 0x01,
198 | 0xFF, 0xC0, 0x1F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x03, 0x80, 0x00,
199 | 0x30, 0x00, 0x02, 0x00, 0x00, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03,
201 | 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0,
202 | 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
203 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF,
204 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
205 | 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0,
206 | 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07,
207 | 0xCF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x8F,
208 | 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80,
209 | 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00,
210 | 0x3E, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
211 | 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03,
212 | 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07,
213 | 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xF0, 0x0F,
214 | 0xFF, 0xFF, 0xF7, 0xFF, 0xFE, 0x7F, 0xFF, 0xC7, 0xFF, 0xF8, 0x3F, 0xFF,
215 | 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x1F, 0xE0, 0x01, 0xF8,
216 | 0x00, 0x1E, 0x00, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF,
217 | 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F,
218 | 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07, 0xCF, 0xBF, 0xFF, 0x3E,
219 | 0x7F, 0xFC, 0xF8, 0xFF, 0xF3, 0xE3, 0xFF, 0x8F, 0x87, 0xFE, 0x3E, 0x1F,
220 | 0x00, 0xF8, 0x3E, 0x03, 0xE0, 0xFC, 0x0F, 0x81, 0xF0, 0x3E, 0x03, 0xE0,
221 | 0xF8, 0x0F, 0x83, 0xE0, 0x1F, 0x0F, 0x80, 0x7E, 0x3E, 0x00, 0xF8, 0x00,
222 | 0x03, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x03, 0xFF,
223 | 0xFE, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0x81, 0xFF, 0xFE,
224 | 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00, 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00,
225 | 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF,
226 | 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0x80, 0x00, 0x3F, 0x00, 0x00, 0x7C, 0x00,
227 | 0x01, 0xF8, 0x00, 0x07, 0xE0, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x07, 0xFF,
228 | 0xFC, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xE1, 0xFF,
229 | 0xFF, 0xF0, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80,
230 | 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F,
231 | 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00,
232 | 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8,
233 | 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00,
234 | 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0,
235 | 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00,
236 | 0x1C, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x30, 0x00, 0x00, 0x02, 0x00,
237 | 0x00, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF,
238 | 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00,
239 | 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC,
240 | 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07,
241 | 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
242 | 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x3F,
243 | 0x80, 0x07, 0xF8, 0x00, 0xFF, 0x80, 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F,
244 | 0xF8, 0x07, 0xEF, 0x80, 0xFC, 0xF8, 0x1F, 0x8F, 0x83, 0xF0, 0xF8, 0x7F,
245 | 0x0F, 0x8F, 0xE0, 0xF9, 0xFC, 0x0F, 0xBF, 0x80, 0xFB, 0xF0, 0x0F, 0xFE,
246 | 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0xFF, 0x80, 0x0F, 0xF0, 0x00, 0xFE,
247 | 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0E,
248 | 0x00, 0x00, 0xC0, 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0xF8, 0x00,
249 | 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x02, 0x03, 0xFF, 0x01, 0x81, 0xFF, 0x81,
250 | 0xC0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE1, 0xFC, 0x3F, 0xF1, 0xFF, 0x1F, 0xF8,
251 | 0xFF, 0x8F, 0xFC, 0xFF, 0xE7, 0xFE, 0xFF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF,
252 | 0xFE, 0x3F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x01, 0xFF,
253 | 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x03,
254 | 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00,
255 | 0x07, 0xC0, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x20, 0xFC,
256 | 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F, 0x00, 0xFC, 0x3F, 0x81, 0xFC, 0x1F,
257 | 0x83, 0xF8, 0x0F, 0xC3, 0xF0, 0x07, 0xE7, 0xE0, 0x07, 0xFF, 0xE0, 0x03,
258 | 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
259 | 0x7E, 0x00, 0x00, 0xFF, 0x00, 0x01, 0xFF, 0x80, 0x03, 0xFF, 0xC0, 0x03,
260 | 0xFF, 0xC0, 0x07, 0xE7, 0xE0, 0x0F, 0xC3, 0xF0, 0x1F, 0xC3, 0xF8, 0x1F,
261 | 0x81, 0xF8, 0x3F, 0x00, 0xFC, 0x7E, 0x00, 0x7E, 0xFE, 0x00, 0x7F, 0xFE,
262 | 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F, 0x00, 0xFC, 0x1F, 0x81, 0xF8, 0x1F,
263 | 0xC3, 0xF8, 0x0F, 0xC3, 0xF0, 0x07, 0xE7, 0xE0, 0x03, 0xFF, 0xC0, 0x03,
264 | 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00,
265 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
266 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
267 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
268 | 0x7C, 0x00, 0x00, 0x78, 0x00, 0x00, 0x70, 0x00, 0x00, 0x40, 0x00, 0xFF,
269 | 0xFF, 0xDF, 0xFF, 0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0xFC, 0x00,
270 | 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8, 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x07,
271 | 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x03, 0xF0, 0x00, 0xFC,
272 | 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x01, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
273 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF,
274 | 0xFE, 0x3F, 0xF0, 0xFF, 0x83, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03,
275 | 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00,
276 | 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, 0x80,
277 | 0x3E, 0x00, 0xF8, 0x03, 0xFE, 0x0F, 0xFC, 0x3F, 0xF8, 0xFF, 0xF3, 0xFF,
278 | 0xF0, 0x60, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xE0, 0x03,
279 | 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00,
280 | 0x1C, 0x00, 0x78, 0x00, 0xE0, 0x03, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x78,
281 | 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x78, 0x00, 0xE0, 0x03,
282 | 0xC0, 0x07, 0x00, 0x18, 0xFF, 0xFC, 0xFF, 0xF1, 0xFF, 0xC3, 0xFF, 0x07,
283 | 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0,
284 | 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0,
285 | 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x7C,
286 | 0x1F, 0xF0, 0xFF, 0xC7, 0xFF, 0x3F, 0xFF, 0xFF, 0xF0, 0x01, 0xF8, 0x00,
287 | 0x3F, 0x80, 0x03, 0xFC, 0x00, 0x7F, 0xE0, 0x0F, 0x9E, 0x00, 0xF1, 0xF0,
288 | 0x1F, 0x0F, 0x01, 0xE0, 0xF8, 0x3E, 0x07, 0xC7, 0xC0, 0x3C, 0x78, 0x03,
289 | 0xEF, 0x80, 0x1E, 0xF0, 0x01, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
290 | 0xE0, 0xF1, 0xE3, 0x8F, 0x1C, 0x30, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
291 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xE0,
292 | 0x03, 0xFF, 0x03, 0x1F, 0xF8, 0x3C, 0xFF, 0xC1, 0xF7, 0xFE, 0x1F, 0xFF,
293 | 0xF1, 0xFD, 0xFF, 0x9F, 0xCF, 0xFD, 0xFC, 0x7F, 0xEF, 0xC3, 0xFF, 0xFC,
294 | 0x1F, 0xFF, 0xE0, 0xFF, 0xFE, 0x07, 0xFF, 0xE0, 0x3F, 0xFE, 0x01, 0xFF,
295 | 0xF0, 0x0F, 0xFF, 0x00, 0x7F, 0xF0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00,
296 | 0x07, 0x80, 0x00, 0x38, 0x00, 0x01, 0x80, 0x00, 0x08, 0x00, 0x00, 0x40,
297 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, 0xFF,
298 | 0xCF, 0xFF, 0xFC, 0x7C, 0x03, 0xE3, 0xE0, 0x3E, 0x1F, 0x03, 0xE0, 0xF8,
299 | 0x7F, 0xFF, 0xC3, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0xFF, 0xFF, 0x87, 0xFF,
300 | 0xFC, 0x01, 0xFF, 0xE0, 0x0F, 0xDF, 0x00, 0xFC, 0xF8, 0x0F, 0xC7, 0xC0,
301 | 0xFE, 0x3E, 0x07, 0xE1, 0xF0, 0x7E, 0x0F, 0x87, 0xE0, 0x7C, 0x7F, 0x03,
302 | 0xE3, 0xF0, 0x1F, 0x3F, 0x00, 0x03, 0xF0, 0x00, 0x3F, 0x80, 0x01, 0xF8,
303 | 0x00, 0x1F, 0x80, 0x00, 0xF8, 0x00, 0x03, 0xC0, 0x00, 0x04, 0x00, 0x00,
304 | 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF, 0xF8, 0xFF, 0xFF,
305 | 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80,
306 | 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8,
307 | 0x00, 0x0F, 0x80, 0x3E, 0xF8, 0x03, 0xEF, 0x80, 0x3E, 0xF8, 0x03, 0xEF,
308 | 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE,
309 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
310 | 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F,
311 | 0xE0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF,
312 | 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF,
313 | 0xFF, 0xFD, 0xFF, 0xFF, 0x3F, 0xFF, 0xC7, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
314 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
315 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xF0, 0xFF, 0xE0, 0xFF,
316 | 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
317 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
318 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0x80,
319 | 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8,
320 | 0xFF, 0xF8, 0x3F, 0xFC, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E,
321 | 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80,
322 | 0x03, 0xE0, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFE, 0x3F, 0xFF, 0xC7, 0xFF,
323 | 0xF8, 0xFF, 0xFF, 0x0F, 0xC0, 0x00, 0xF8, 0x00, 0x0F, 0x80, 0x00, 0xF8,
324 | 0x1F, 0xFF, 0x83, 0xFF, 0xF8, 0x7F, 0xFF, 0x8F, 0xFF, 0xF9, 0xFF, 0xFF,
325 | 0xA0, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x01, 0xFF, 0x80, 0x1F,
326 | 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
327 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x06, 0x00,
328 | 0x00, 0x70, 0x00, 0x07, 0x80, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F,
329 | 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80,
330 | 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF,
331 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
332 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
333 | 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x00,
334 | 0x0F, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x00, 0x02, 0x00, 0x00, 0x10,
335 | 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
336 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xDE, 0x71, 0x84, 0x20, 0x7F, 0xFE,
337 | 0x7F, 0xFC, 0x7F, 0xF8, 0x7F, 0xF0, 0x7F, 0xE0, 0x07, 0xC0, 0x0F, 0x80,
338 | 0x1F, 0x00, 0x3E, 0x00, 0x7C, 0x00, 0xF8, 0x01, 0xF0, 0x03, 0xF0, 0x07,
339 | 0xE0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F, 0xE0, 0x7F, 0xE0, 0xFF, 0xC1, 0xFF,
340 | 0x83, 0xFF, 0x07, 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF,
341 | 0xC7, 0xFC, 0x0F, 0xE0, 0x1E, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80,
342 | 0x00, 0x07, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xFC, 0xF8, 0x07, 0xE3, 0xE0,
343 | 0x3F, 0x8F, 0x81, 0xFC, 0x3E, 0x0F, 0xE0, 0xF8, 0x7F, 0x03, 0xE3, 0xF8,
344 | 0x0F, 0x9F, 0xC0, 0x3E, 0xFE, 0x00, 0xFF, 0xF0, 0x03, 0xFF, 0x80, 0x0F,
345 | 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0xC0, 0x0F, 0xFF,
346 | 0x80, 0x3F, 0x7F, 0x00, 0xF8, 0xFC, 0x03, 0xE1, 0xF8, 0x0F, 0x87, 0xF0,
347 | 0x3E, 0x0F, 0xC0, 0xF8, 0x1F, 0x83, 0xE0, 0x7F, 0x0F, 0x80, 0xFC, 0x3E,
348 | 0x01, 0xF8, 0xF8, 0x03, 0xF1, 0xE0, 0x0F, 0xC3, 0x80, 0x1F, 0x86, 0x00,
349 | 0x3F, 0x18, 0x00, 0xFC, 0x20, 0x01, 0xE0, 0x80, 0x02, 0x00, 0x80, 0x00,
350 | 0x38, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
351 | 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0,
352 | 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00,
353 | 0x3E, 0x00, 0x0F, 0x80, 0x03, 0xE0, 0x00, 0xF8, 0x00, 0x3E, 0x00, 0x0F,
354 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80,
355 | 0x00, 0x00, 0xC0, 0x00, 0x00, 0x70, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x7F,
356 | 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xF8, 0x00, 0x3F,
357 | 0xFE, 0x00, 0x3F, 0xFF, 0x80, 0x3F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x1F,
358 | 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xF7, 0xEF,
359 | 0xDF, 0xFB, 0xFF, 0xEF, 0xFC, 0xFF, 0xE7, 0xFE, 0x3F, 0xE3, 0xFF, 0x0F,
360 | 0xE1, 0xFF, 0x87, 0xF0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE0, 0x70, 0x3F, 0xF0,
361 | 0x10, 0x1F, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x00, 0x03, 0xE0,
362 | 0x80, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x70, 0x01, 0xFF, 0x00, 0x3F,
363 | 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xE0, 0x1F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F,
364 | 0xFE, 0x0F, 0xFF, 0xE1, 0xFF, 0xFE, 0x3F, 0xFF, 0xE7, 0xFE, 0xFE, 0xFF,
365 | 0xCF, 0xDF, 0xF8, 0xFF, 0xFF, 0x0F, 0xFF, 0xE1, 0xFF, 0xFC, 0x1F, 0xFF,
366 | 0x81, 0xFF, 0xF0, 0x1F, 0xFE, 0x01, 0xFF, 0xC0, 0x1F, 0xF8, 0x01, 0xFF,
367 | 0x00, 0x3F, 0xE0, 0x03, 0x80, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x40,
368 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
369 | 0xFF, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF,
370 | 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00,
371 | 0x7F, 0xE0, 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE,
372 | 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
373 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF,
374 | 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00,
375 | 0x7C, 0xF8, 0x01, 0xF3, 0xE0, 0x07, 0xCF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC,
376 | 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0xF8,
377 | 0x00, 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00, 0x00, 0xF8, 0x00,
378 | 0x03, 0xE0, 0x00, 0x0F, 0x80, 0x00, 0x3E, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
379 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFE,
380 | 0x00, 0xFF, 0xC0, 0x1F, 0xF8, 0x03, 0xFF, 0x00, 0x7F, 0xE0, 0x0F, 0xFC,
381 | 0x01, 0xFF, 0x80, 0x3F, 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x1F, 0xF8,
382 | 0x03, 0xFF, 0x00, 0x7F, 0xF0, 0x0F, 0xFF, 0xFF, 0xF7, 0xFF, 0xFE, 0x7F,
383 | 0xFF, 0xC7, 0xFF, 0xF8, 0x3F, 0xFF, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03,
384 | 0xFC, 0x00, 0x1F, 0xE0, 0x01, 0xF8, 0x00, 0x1E, 0x00, 0x01, 0x80, 0xFF,
385 | 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF,
386 | 0xFB, 0xE0, 0x03, 0xEF, 0x80, 0x1F, 0xBE, 0x00, 0x7C, 0xF8, 0x01, 0xF3,
387 | 0xE0, 0x07, 0xCF, 0xBF, 0xFF, 0x3E, 0x7F, 0xFC, 0xF8, 0xFF, 0xF3, 0xE3,
388 | 0xFF, 0x8F, 0x87, 0xFE, 0x3E, 0x1F, 0x00, 0xF8, 0x3E, 0x03, 0xE0, 0xFC,
389 | 0x0F, 0x81, 0xF0, 0x3E, 0x03, 0xE0, 0xF8, 0x0F, 0x83, 0xE0, 0x1F, 0x0F,
390 | 0x80, 0x7E, 0x3E, 0x00, 0xF8, 0x00, 0x03, 0xE0, 0x00, 0x07, 0x00, 0x00,
391 | 0x08, 0x00, 0x00, 0x40, 0x03, 0xFF, 0xFE, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF,
392 | 0xE0, 0x7F, 0xFF, 0x81, 0xFF, 0xFE, 0x03, 0xF0, 0x00, 0x0F, 0xC0, 0x00,
393 | 0x1F, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB,
394 | 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0x80,
395 | 0x00, 0x3F, 0x00, 0x00, 0x7C, 0x00, 0x01, 0xF8, 0x00, 0x07, 0xE0, 0xFF,
396 | 0xFF, 0x81, 0xFF, 0xFF, 0x07, 0xFF, 0xFC, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF,
397 | 0xE0, 0x03, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFC, 0x1F,
398 | 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0,
399 | 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00,
400 | 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x3E, 0x00,
401 | 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x03,
402 | 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, 0x80, 0x00, 0x01, 0xF0, 0x00,
403 | 0x00, 0x3E, 0x00, 0x00, 0x07, 0xC0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x1F,
404 | 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x01, 0x80, 0x00,
405 | 0x00, 0x30, 0x00, 0x00, 0x02, 0x00, 0x00, 0xF8, 0x00, 0xFF, 0xC0, 0x07,
406 | 0xFE, 0x00, 0x3F, 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0,
407 | 0x03, 0xFF, 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F,
408 | 0xF0, 0x01, 0xFF, 0x80, 0x0F, 0xFC, 0x00, 0x7F, 0xE0, 0x03, 0xFF, 0x00,
409 | 0x1F, 0xF8, 0x00, 0xFF, 0xC0, 0x07, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF,
410 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
411 | 0x1F, 0x80, 0x01, 0xF8, 0x00, 0x3F, 0x80, 0x07, 0xF8, 0x00, 0xFF, 0x80,
412 | 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F, 0xF8, 0x07, 0xEF, 0x80, 0xFC, 0xF8,
413 | 0x1F, 0x8F, 0x83, 0xF0, 0xF8, 0x7F, 0x0F, 0x8F, 0xE0, 0xF9, 0xFC, 0x0F,
414 | 0xBF, 0x80, 0xFB, 0xF0, 0x0F, 0xFE, 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00,
415 | 0xFF, 0x80, 0x0F, 0xF0, 0x00, 0xFE, 0x00, 0x0F, 0xC0, 0x00, 0xF8, 0x00,
416 | 0x0F, 0x00, 0x00, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0xC0, 0x00, 0x08, 0x00,
417 | 0x00, 0x80, 0x00, 0x00, 0xF8, 0x00, 0x0F, 0xFC, 0x00, 0x07, 0xFE, 0x02,
418 | 0x03, 0xFF, 0x01, 0x81, 0xFF, 0x81, 0xC0, 0xFF, 0xC1, 0xF0, 0x7F, 0xE1,
419 | 0xFC, 0x3F, 0xF1, 0xFF, 0x1F, 0xF8, 0xFF, 0x8F, 0xFC, 0xFF, 0xE7, 0xFE,
420 | 0xFF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFE, 0x0F, 0xFF,
421 | 0xFF, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x00, 0x1F,
422 | 0xFF, 0x80, 0x0F, 0xFF, 0x80, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00,
423 | 0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x07, 0xC0, 0x00, 0x01, 0xC0, 0x00,
424 | 0x00, 0x60, 0x00, 0x00, 0x20, 0xFC, 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F,
425 | 0x00, 0xFC, 0x3F, 0x81, 0xFC, 0x1F, 0x83, 0xF8, 0x0F, 0xC3, 0xF0, 0x07,
426 | 0xE7, 0xE0, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00,
427 | 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0xFF, 0x00, 0x01,
428 | 0xFF, 0x80, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xC0, 0x07, 0xE7, 0xE0, 0x0F,
429 | 0xC3, 0xF0, 0x1F, 0xC3, 0xF8, 0x1F, 0x81, 0xF8, 0x3F, 0x00, 0xFC, 0x7E,
430 | 0x00, 0x7E, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0x7E, 0x00, 0x7E, 0x3F,
431 | 0x00, 0xFC, 0x1F, 0x81, 0xF8, 0x1F, 0xC3, 0xF8, 0x0F, 0xC3, 0xF0, 0x07,
432 | 0xE7, 0xE0, 0x03, 0xFF, 0xC0, 0x03, 0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x00,
433 | 0xFF, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
434 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
435 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00,
436 | 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x78, 0x00, 0x00,
437 | 0x70, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFB, 0xFF, 0xFF,
438 | 0x7F, 0xFF, 0xEF, 0xFF, 0xFC, 0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8,
439 | 0x00, 0xFE, 0x00, 0x3F, 0x80, 0x07, 0xE0, 0x01, 0xFC, 0x00, 0x7F, 0x00,
440 | 0x1F, 0xC0, 0x03, 0xF0, 0x00, 0xFC, 0x00, 0x3F, 0x80, 0x0F, 0xE0, 0x01,
441 | 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
442 | 0xFF, 0xFF, 0x00, 0xFF, 0xE0, 0x7F, 0xF8, 0x1F, 0xFE, 0x07, 0xFF, 0x01,
443 | 0xFF, 0xC0, 0x3F, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03,
444 | 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0x3F,
445 | 0xC0, 0x07, 0xF8, 0x00, 0xFF, 0x00, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F,
446 | 0x80, 0x01, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F,
447 | 0x80, 0x03, 0xFF, 0x80, 0x3F, 0xF8, 0x03, 0xFF, 0xC0, 0x1F, 0xFC, 0x01,
448 | 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF,
449 | 0xE0, 0x0F, 0xFF, 0x00, 0xFF, 0xF0, 0x07, 0xFF, 0x00, 0x7F, 0xF0, 0x00,
450 | 0x7E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x1F, 0x00, 0x03, 0xE0, 0x00,
451 | 0x7C, 0x00, 0x0F, 0x80, 0x01, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00,
452 | 0xFF, 0x00, 0x1F, 0xE0, 0x03, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0x80, 0x01,
453 | 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xC0, 0x00, 0xF8, 0x00, 0x3F, 0x00, 0xFF,
454 | 0xE0, 0x3F, 0xF8, 0x1F, 0xFE, 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0x00, 0x3F,
455 | 0x00, 0x0F, 0xF8, 0x03, 0xFF, 0xC3, 0x30, 0xFF, 0xF4, 0x07, 0xFC, 0x00,
456 | 0x1F, 0x00 };
457 |
458 | const GFXglyph Fun_Games20pt7bGlyphs[] PROGMEM = {
459 | { 0, 1, 1, 10, 0, 0 }, // 0x20 ' '
460 | { 1, 5, 26, 9, 2, -25 }, // 0x21 '!'
461 | { 18, 7, 7, 11, 2, -23 }, // 0x22 '"'
462 | { 25, 22, 28, 25, 2, -25 }, // 0x23 '#'
463 | { 102, 24, 32, 27, 1, -27 }, // 0x24 '$'
464 | { 198, 15, 24, 18, 2, -23 }, // 0x25 '%'
465 | { 243, 22, 24, 25, 2, -23 }, // 0x26 '&'
466 | { 309, 3, 7, 6, 2, -23 }, // 0x27 '''
467 | { 312, 16, 30, 19, 2, -23 }, // 0x28 '('
468 | { 372, 16, 30, 20, 2, -23 }, // 0x29 ')'
469 | { 432, 10, 10, 13, 2, -24 }, // 0x2A '*'
470 | { 445, 21, 21, 23, 1, -23 }, // 0x2B '+'
471 | { 501, 5, 11, 9, 2, -4 }, // 0x2C ','
472 | { 508, 13, 5, 17, 2, -12 }, // 0x2D '-'
473 | { 517, 5, 5, 9, 2, -4 }, // 0x2E '.'
474 | { 521, 14, 29, 18, 2, -27 }, // 0x2F '/'
475 | { 572, 21, 24, 25, 2, -23 }, // 0x30 '0'
476 | { 635, 10, 30, 14, 2, -23 }, // 0x31 '1'
477 | { 673, 23, 24, 27, 2, -23 }, // 0x32 '2'
478 | { 742, 19, 24, 23, 2, -23 }, // 0x33 '3'
479 | { 799, 19, 31, 23, 2, -23 }, // 0x34 '4'
480 | { 873, 23, 24, 27, 2, -23 }, // 0x35 '5'
481 | { 942, 21, 24, 25, 2, -23 }, // 0x36 '6'
482 | { 1005, 19, 30, 20, 0, -23 }, // 0x37 '7'
483 | { 1077, 21, 24, 25, 2, -23 }, // 0x38 '8'
484 | { 1140, 21, 24, 25, 2, -23 }, // 0x39 '9'
485 | { 1203, 5, 21, 9, 2, -20 }, // 0x3A ':'
486 | { 1217, 5, 27, 9, 2, -20 }, // 0x3B ';'
487 | { 1234, 13, 21, 16, 2, -23 }, // 0x3C '<'
488 | { 1269, 19, 11, 23, 2, -18 }, // 0x3D '='
489 | { 1296, 13, 21, 16, 1, -23 }, // 0x3E '>'
490 | { 1331, 19, 24, 23, 2, -23 }, // 0x3F '?'
491 | { 1388, 20, 21, 24, 2, -23 }, // 0x40 '@'
492 | { 1441, 21, 30, 25, 2, -23 }, // 0x41 'A'
493 | { 1520, 21, 31, 25, 2, -23 }, // 0x42 'B'
494 | { 1602, 20, 24, 24, 2, -23 }, // 0x43 'C'
495 | { 1662, 19, 24, 23, 2, -23 }, // 0x44 'D'
496 | { 1719, 16, 24, 20, 2, -23 }, // 0x45 'E'
497 | { 1767, 18, 24, 22, 2, -23 }, // 0x46 'F'
498 | { 1821, 20, 24, 24, 2, -23 }, // 0x47 'G'
499 | { 1881, 21, 36, 25, 2, -29 }, // 0x48 'H'
500 | { 1976, 5, 31, 9, 2, -24 }, // 0x49 'I'
501 | { 1996, 15, 31, 18, 2, -23 }, // 0x4A 'J'
502 | { 2055, 22, 35, 23, 2, -27 }, // 0x4B 'K'
503 | { 2152, 18, 27, 22, 2, -26 }, // 0x4C 'L'
504 | { 2213, 25, 27, 29, 2, -26 }, // 0x4D 'M'
505 | { 2298, 19, 30, 23, 2, -26 }, // 0x4E 'N'
506 | { 2370, 21, 24, 25, 2, -23 }, // 0x4F 'O'
507 | { 2433, 22, 24, 25, 2, -23 }, // 0x50 'P'
508 | { 2499, 19, 31, 23, 2, -23 }, // 0x51 'Q'
509 | { 2573, 22, 28, 24, 2, -23 }, // 0x52 'R'
510 | { 2650, 23, 24, 27, 2, -23 }, // 0x53 'S'
511 | { 2719, 27, 30, 27, 0, -23 }, // 0x54 'T'
512 | { 2821, 21, 24, 25, 2, -23 }, // 0x55 'U'
513 | { 2884, 20, 31, 23, 2, -23 }, // 0x56 'V'
514 | { 2962, 25, 27, 29, 2, -23 }, // 0x57 'W'
515 | { 3047, 24, 24, 28, 2, -23 }, // 0x58 'X'
516 | { 3119, 24, 28, 28, 2, -23 }, // 0x59 'Y'
517 | { 3203, 19, 24, 22, 2, -23 }, // 0x5A 'Z'
518 | { 3260, 14, 30, 17, 2, -23 }, // 0x5B '['
519 | { 3313, 14, 29, 18, 2, -27 }, // 0x5C '\'
520 | { 3364, 14, 30, 17, 1, -23 }, // 0x5D ']'
521 | { 3417, 20, 13, 24, 2, -23 }, // 0x5E '^'
522 | { 3450, 17, 3, 20, 2, 4 }, // 0x5F '_'
523 | { 3457, 6, 8, 9, 2, -29 }, // 0x60 '`'
524 | { 3463, 21, 30, 25, 2, -23 }, // 0x61 'a'
525 | { 3542, 21, 31, 25, 2, -23 }, // 0x62 'b'
526 | { 3624, 20, 24, 24, 2, -23 }, // 0x63 'c'
527 | { 3684, 19, 24, 23, 2, -23 }, // 0x64 'd'
528 | { 3741, 16, 24, 20, 2, -23 }, // 0x65 'e'
529 | { 3789, 18, 24, 22, 2, -23 }, // 0x66 'f'
530 | { 3843, 20, 24, 24, 2, -23 }, // 0x67 'g'
531 | { 3903, 21, 36, 25, 2, -29 }, // 0x68 'h'
532 | { 3998, 5, 31, 9, 2, -24 }, // 0x69 'i'
533 | { 4018, 15, 31, 18, 2, -23 }, // 0x6A 'j'
534 | { 4077, 22, 35, 23, 2, -27 }, // 0x6B 'k'
535 | { 4174, 18, 27, 22, 2, -26 }, // 0x6C 'l'
536 | { 4235, 25, 27, 29, 2, -26 }, // 0x6D 'm'
537 | { 4320, 19, 30, 23, 2, -26 }, // 0x6E 'n'
538 | { 4392, 21, 24, 25, 2, -23 }, // 0x6F 'o'
539 | { 4455, 22, 24, 25, 2, -23 }, // 0x70 'p'
540 | { 4521, 19, 31, 23, 2, -23 }, // 0x71 'q'
541 | { 4595, 22, 28, 24, 2, -23 }, // 0x72 'r'
542 | { 4672, 23, 24, 27, 2, -23 }, // 0x73 's'
543 | { 4741, 27, 30, 27, 0, -23 }, // 0x74 't'
544 | { 4843, 21, 24, 25, 2, -23 }, // 0x75 'u'
545 | { 4906, 20, 31, 23, 2, -23 }, // 0x76 'v'
546 | { 4984, 25, 27, 29, 2, -23 }, // 0x77 'w'
547 | { 5069, 24, 24, 28, 2, -23 }, // 0x78 'x'
548 | { 5141, 24, 28, 28, 2, -23 }, // 0x79 'y'
549 | { 5225, 19, 24, 22, 2, -23 }, // 0x7A 'z'
550 | { 5282, 19, 30, 23, 2, -23 }, // 0x7B '{'
551 | { 5354, 2, 34, 6, 2, -26 }, // 0x7C '|'
552 | { 5363, 19, 30, 23, 2, -23 }, // 0x7D '}'
553 | { 5435, 19, 6, 23, 2, -19 } }; // 0x7E '~'
554 |
555 | const GFXfont Fun_Games20pt7b PROGMEM = {
556 | (uint8_t *)Fun_Games20pt7bBitmaps,
557 | (GFXglyph *)Fun_Games20pt7bGlyphs,
558 | 0x20, 0x7E, 40 };
559 |
560 | // Approx. 6122 bytes
561 |
--------------------------------------------------------------------------------
/image_test.h:
--------------------------------------------------------------------------------
1 | #include "virtualScreen.h"
2 | #include "images/newyork_960x240.h"
3 | #include "images/highway_720x480.h"
4 | #include "images/night_earth_960x240.h"
5 | #include "images/bazar_960x240.h"
6 | #include "images/spacebattle_960x240.h"
7 | #include "images/console_960x240.h"
8 |
9 | // #define test_image bazar
10 | // #define test_width bazar_width
11 | // #define test_height bazar_height
12 |
13 | // #define test_image spacebattle
14 | // #define test_width spacebattle_width
15 | // #define test_height spacebattle_height
16 |
17 | // #define test_image console
18 | // #define test_width console_width
19 | // #define test_height console_height
20 |
21 | #define test_image highway
22 | #define test_width highway_width
23 | #define test_height highway_height
24 |
25 | void image_test(VirtualDisplay *tft)
26 | {
27 | tft->fillScreen(TFT_BLACK);
28 | tft->drawRGBBitmap(0, 0, (uint16_t *)test_image, test_width, test_height);
29 | tft->output();
30 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | [Keywords]
2 | #######################################
3 | # Datatypes (KEYWORD1)
4 | #######################################
5 | boolean
6 | uint16_t
7 | int
8 |
9 | #######################################
10 | # Methods and Functions (KEYWORD2)
11 | #######################################
12 | begin KEYWORD2
13 | output KEYWORD2
14 | highlightArea KEYWORD2
15 | color565 KEYWORD2
16 | readRect KEYWORD2
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=VirtualScreen
2 | version=2.0.2
3 | author=The Last Outpost Workshop
4 | maintainer=The Last Outpost Workshop
5 | sentence=Automatically span GFX Adafruit graphics functions across multiple screens
6 | paragraph=Works with any 16 bit SPI Screen supported by TFT_eSPI on ESP32
7 | category=Display
8 | keywords=keywords.txt
9 | url=https://github.com/thelastoutpostworkshop/virtualScreen
10 | architectures=esp32
11 | depends=Adafruit GFX Library, TFT_eSPI
--------------------------------------------------------------------------------
/oldino:
--------------------------------------------------------------------------------
1 | #include "virtualScreen.h"
2 |
3 | #include "gameoflife.h"
4 | #include "maze.h"
5 | #include "playPong.h"
6 | #include "tetris.h"
7 | #include "font_test.h"
8 | #include "image_test.h"
9 |
10 | VirtualDisplay *tft;
11 |
12 |
13 | void setup()
14 | {
15 | Serial.begin(115200);
16 |
17 | ScreenBuilder screens;
18 |
19 | // 4 sreens on one row
20 | screens.addRow({{16, 0}, {15, 0}, {6, 0}, {7, 0}});
21 |
22 | // 6 screens 3 on each row
23 | // screens.addRow({{7, 2}, {6, 2}, {15, 2}});
24 | // screens.addRow({{16, 0}, {11, 0}, {9, 0}});
25 |
26 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
27 |
28 | if (!tft->begin())
29 | {
30 | Serial.println("Memory Allocation for virtual screen failed");
31 | return;
32 | }
33 |
34 | // Demonstrations
35 | //
36 |
37 | // playPong(tft);
38 | gameOfLife(tft);
39 | // solveMaze(tft);
40 | // font_test(tft);
41 | // image_test(tft);
42 | // playTetris(tft);
43 | // runNostromoSimulation(tft);
44 | }
45 |
46 | void loop()
47 | {
48 | }
49 |
--------------------------------------------------------------------------------
/src/virtualScreen.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #ifndef _VIRTUAL_SCREEN_
6 | #define _VIRTUAL_SCREEN_
7 |
8 | #define pixelSize 2 // Pixel Size in bytes
9 |
10 | TFT_eSPI physicalDisplayTFT = TFT_eSPI();
11 |
12 | typedef struct
13 | {
14 | int cs;
15 | int rotation;
16 | } ScreenRow;
17 |
18 | typedef struct
19 | {
20 | int row;
21 | int column;
22 | int cs;
23 | int rotation;
24 | bool dirty;
25 | } Screen;
26 |
27 | class ScreenBuilder
28 | {
29 | std::vector screens;
30 | int totalRows = 0;
31 | int maxColumns = 0;
32 | int virtualScreenWidth = 0;
33 | int virtualScreenHeight = 0;
34 |
35 | public:
36 | ScreenBuilder &addRow(std::initializer_list screenRows)
37 | {
38 | int columnCount = screenRows.size();
39 | maxColumns = std::max(maxColumns, columnCount);
40 | int column = 0;
41 | for (const auto &screenRow : screenRows)
42 | {
43 | screens.push_back({totalRows, column, screenRow.cs, screenRow.rotation});
44 | ++column;
45 | }
46 | ++totalRows;
47 |
48 | // Update virtual screen dimensions
49 | virtualScreenWidth = physicalDisplayTFT.width() * maxColumns;
50 | virtualScreenHeight = physicalDisplayTFT.height() * totalRows;
51 |
52 | return *this;
53 | }
54 |
55 | std::vector &getScreens()
56 | {
57 | return screens;
58 | }
59 |
60 | Screen *getScreen(int x, int y)
61 | {
62 | // Calculate which row and column the x, y coordinates fall into
63 | int column = x / physicalDisplayTFT.width();
64 | int row = y / physicalDisplayTFT.height();
65 |
66 | // Iterate through the screens to find the matching one
67 | for (auto &screen : screens)
68 | {
69 | if (screen.row == row && screen.column == column)
70 | {
71 | return &screen; // Return the address of the screen
72 | }
73 | }
74 |
75 | // If no matching screen is found, return a null pointer
76 | return nullptr;
77 | }
78 |
79 | int width() const
80 | {
81 | return virtualScreenWidth;
82 | }
83 |
84 | int height() const
85 | {
86 | return virtualScreenHeight;
87 | }
88 | };
89 |
90 | class VirtualDisplay : public Adafruit_GFX
91 | {
92 | private:
93 | uint16_t *canvas;
94 | size_t canvasSize;
95 | size_t displayBufferSize;
96 | uint16_t *displayBuffer;
97 | int16_t _width;
98 | int16_t _height;
99 | bool _ready = false;
100 | ScreenBuilder *screenBuilder;
101 |
102 | inline bool checkReady() const
103 | {
104 | return _ready;
105 | }
106 |
107 | void clearDisplayBuffer()
108 | {
109 | memset(canvas, 0, displayBufferSize);
110 | }
111 |
112 | uint16_t *getScreenImage(const Screen &screen)
113 | {
114 | // Calculate the starting position of the screen in the buffer
115 | uint32_t position = (screen.row * physicalDisplayTFT.height() * screenBuilder->width()) + (screen.column * physicalDisplayTFT.width());
116 |
117 | uint16_t *startPos = canvas + position;
118 |
119 | // Copy the screen image from the buffer
120 | for (int y = 0; y < physicalDisplayTFT.height(); ++y)
121 | {
122 | for (int x = 0; x < physicalDisplayTFT.width(); ++x)
123 | {
124 | displayBuffer[y * physicalDisplayTFT.width() + x] = startPos[y * screenBuilder->width() + x];
125 | }
126 | }
127 |
128 | return displayBuffer;
129 | }
130 |
131 | void clearDirtyFlag()
132 | {
133 | auto &screens = screenBuilder->getScreens();
134 |
135 | for (auto &screen : screens)
136 | {
137 | screen.dirty = false;
138 | }
139 | }
140 | void initPhysicalScreens()
141 | {
142 | physicalDisplayTFT.begin();
143 | physicalDisplayTFT.setSwapBytes(true);
144 | const auto &screens = screenBuilder->getScreens();
145 |
146 | for (const auto &screen : screens)
147 | {
148 | pinMode(screen.cs, OUTPUT);
149 | digitalWrite(screen.cs, HIGH);
150 | }
151 | clearDirtyFlag();
152 | }
153 |
154 | // Method to adjust color brightness
155 | uint16_t adjustBrightness(uint16_t color, float intensity)
156 | {
157 | // Decompose the color into its RGB components
158 | uint8_t r = (color >> 11) & 0x1F;
159 | uint8_t g = (color >> 5) & 0x3F;
160 | uint8_t b = color & 0x1F;
161 |
162 | // Increase brightness according to the specified intensity, ensuring no overflow
163 | r = std::min(31.0f, r * (1.0f + intensity));
164 | g = std::min(63.0f, g * (1.0f + intensity));
165 | b = std::min(31.0f, b * (1.0f + intensity));
166 |
167 | // Recompose the color
168 | return (r << 11) | (g << 5) | b;
169 | }
170 |
171 | public:
172 | VirtualDisplay(int16_t w, int16_t h, ScreenBuilder *builder) : Adafruit_GFX(w, h)
173 | {
174 | _width = w;
175 | _height = h;
176 | canvasSize = w * h * pixelSize;
177 | if ((canvas = (uint16_t *)malloc(canvasSize)))
178 | {
179 | memset(canvas, 0, canvasSize);
180 | }
181 | displayBufferSize = physicalDisplayTFT.width() * physicalDisplayTFT.height() * pixelSize;
182 | if ((displayBuffer = (uint16_t *)malloc(displayBufferSize)))
183 | {
184 | clearDisplayBuffer();
185 | }
186 | _ready = canvas && displayBuffer;
187 | if (!_ready)
188 | {
189 | Serial.println(">>> Not enough memory for virtual screen");
190 | Serial.println(">>> Enable PSRAM in your board configuration if supported");
191 | }
192 | screenBuilder = builder;
193 | }
194 |
195 | bool begin()
196 | {
197 | if (_ready)
198 | {
199 | initPhysicalScreens();
200 | Serial.printf("Virtual Screen Width=%d\n", _width);
201 | Serial.printf("Virtual Screen Height=%d\n", _height);
202 | }
203 | return _ready;
204 | }
205 |
206 | void output()
207 | {
208 | if (!checkReady())
209 | return;
210 |
211 | const auto &screens = screenBuilder->getScreens();
212 |
213 | for (const auto &screen : screens)
214 | {
215 |
216 | uint16_t *screenImage = getScreenImage(screen);
217 | if (screen.dirty)
218 | {
219 | digitalWrite(screen.cs, LOW);
220 | physicalDisplayTFT.setRotation(screen.rotation);
221 | physicalDisplayTFT.pushImage(0, 0, physicalDisplayTFT.width(), physicalDisplayTFT.height(), screenImage);
222 | digitalWrite(screen.cs, HIGH);
223 | }
224 | }
225 | clearDirtyFlag();
226 | }
227 |
228 | // Method to highlight a specified area of the canvas with adjustable intensity
229 | void highlightArea(int16_t x, int16_t y, int16_t width, int16_t height, float intensity)
230 | {
231 | if (!checkReady())
232 | return;
233 |
234 | for (int16_t row = y; row < y + height; ++row)
235 | {
236 | for (int16_t col = x; col < x + width; ++col)
237 | {
238 | if (col >= 0 && col < _width && row >= 0 && row < _height)
239 | {
240 | // Fetch the original color from the canvas
241 | uint16_t originalColor = canvas[row * _width + col];
242 |
243 | // Adjust the color brightness based on the specified intensity
244 | uint16_t adjustedColor = adjustBrightness(originalColor, intensity);
245 |
246 | // Update the pixel on the canvas
247 | drawPixel(col, row, adjustedColor);
248 | }
249 | }
250 | }
251 | }
252 |
253 | // Method to highlight a circular area of the canvas with adjustable intensity
254 | void highlightArea(int16_t centerX, int16_t centerY, int16_t radius, float intensity)
255 | {
256 | if (!checkReady())
257 | return;
258 |
259 | for (int16_t y = centerY - radius; y <= centerY + radius; ++y)
260 | {
261 | for (int16_t x = centerX - radius; x <= centerX + radius; ++x)
262 | {
263 | // Calculate distance from the center of the circle
264 | int16_t dx = x - centerX;
265 | int16_t dy = y - centerY;
266 | if (dx * dx + dy * dy <= radius * radius)
267 | {
268 | // The pixel is inside the circle
269 | if (x >= 0 && x < _width && y >= 0 && y < _height)
270 | {
271 | uint16_t originalColor = canvas[y * _width + x];
272 | uint16_t highlightedColor = adjustBrightness(originalColor, intensity);
273 | drawPixel(x, y, highlightedColor);
274 | }
275 | }
276 | }
277 | }
278 | }
279 |
280 | ~VirtualDisplay()
281 | {
282 | if (canvas)
283 | {
284 | free(canvas);
285 | free(displayBuffer);
286 | }
287 | }
288 |
289 | uint16_t color565(uint8_t r, uint8_t g, uint8_t b)
290 | {
291 | return (uint16_t)((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
292 | }
293 |
294 | int16_t width()
295 | {
296 | return _width;
297 | }
298 | int16_t height()
299 | {
300 | return _height;
301 | }
302 |
303 | void pushImage(int16_t x, int16_t y, int16_t width, int16_t height, uint16_t *buffer)
304 | {
305 | if (!checkReady())
306 | return;
307 |
308 | if (x < 0)
309 | {
310 | x = 0;
311 | }
312 | if (y < 0)
313 | {
314 | y = 0;
315 | }
316 | if (x + width > _width)
317 | {
318 | x = _width;
319 | }
320 | if (y + height > _height)
321 | {
322 | y = _height;
323 | }
324 |
325 | for (int16_t i = 0; i < height; i++)
326 | {
327 | for (int16_t j = 0; j < width; j++)
328 | {
329 | int bufferIndex = i * width + j;
330 |
331 | int canvasIndex = (y + i) * _width + (x + j);
332 |
333 | drawPixel(x + j, y + i, buffer[bufferIndex]);
334 | }
335 | }
336 | }
337 |
338 | void readRect(int16_t x, int16_t y, int16_t width, int16_t height, uint16_t *buffer)
339 | {
340 | if (!checkReady())
341 | return;
342 |
343 | if (x < 0)
344 | {
345 | x = 0;
346 | }
347 | if (y < 0)
348 | {
349 | y = 0;
350 | }
351 | if (x + width > _width)
352 | {
353 | x = _width;
354 | }
355 | if (y + height > _height)
356 | {
357 | y = _height;
358 | }
359 |
360 | for (int16_t row = 0; row < height; ++row)
361 | {
362 | for (int16_t col = 0; col < width; ++col)
363 | {
364 | int canvasIndex = ((y + row) * _width) + (x + col);
365 | int bufferIndex = (row * width) + col;
366 | buffer[bufferIndex] = canvas[canvasIndex];
367 | }
368 | }
369 | }
370 | void drawPixel(int16_t x, int16_t y, uint16_t color) override
371 | {
372 | if (!checkReady())
373 | return;
374 |
375 | if ((x < 0) || (y < 0) || (x >= _width) || (y >= _height))
376 | {
377 | return;
378 | }
379 |
380 | Screen *screen = screenBuilder->getScreen(x, y);
381 |
382 | if (screen)
383 | {
384 | screen->dirty = true;
385 | }
386 |
387 | canvas[y * _width + x] = color;
388 | }
389 |
390 | void startWrite(void) override
391 | {
392 | }
393 |
394 | void endWrite(void) override
395 | {
396 | }
397 | };
398 |
399 | #endif
400 |
--------------------------------------------------------------------------------
/virtualScreen.ino:
--------------------------------------------------------------------------------
1 | #include "src/virtualScreen.h"
2 | #include "images/spacedock_480x480.h"
3 | #include "images/spaceship_480x480.h"
4 |
5 | VirtualDisplay *tft;
6 | ScreenBuilder screens;
7 |
8 | void setup()
9 | {
10 | Serial.begin(115200);
11 |
12 | // Adjust this setup according to your actual screen configuration
13 | screens.addRow({{6, 0}, {7, 0}});
14 | screens.addRow({{16, 2}, {15, 2}});
15 |
16 | tft = new VirtualDisplay(screens.width(), screens.height(), &screens);
17 | tft->begin();
18 |
19 | tft->fillScreen(TFT_BLACK);
20 | tft->drawRGBBitmap(0, 0, (uint16_t *)spaceship_480x480, spaceship_480x480_width, spaceship_480x480_height);
21 | tft->output();
22 | delay(5000);
23 | tft->drawRGBBitmap(0, 0, (uint16_t *)spacedock_480x480, spacedock_480x480_width, spacedock_480x480_height);
24 | tft->output();
25 | }
26 |
27 | void loop()
28 | {
29 | }
30 |
31 |
--------------------------------------------------------------------------------
|