Skip to content

Commit 327d43b

Browse files
shadow578EvilGremlin
authored andcommitted
✨ Games for E3V2 + MarlinUI (MarlinFirmware#27620)
1 parent 4ed97c3 commit 327d43b

File tree

15 files changed

+808
-94
lines changed

15 files changed

+808
-94
lines changed

Marlin/Configuration_adv.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,17 +2046,17 @@
20462046
//#define STATUS_HEAT_PERCENT // Show heating in a progress bar
20472047
//#define STATUS_HEAT_POWER // Show heater output power as a vertical bar
20482048

2049-
// Frivolous Game Options
2050-
//#define MARLIN_BRICKOUT
2051-
//#define MARLIN_INVADERS
2052-
//#define MARLIN_SNAKE
2053-
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu
2054-
20552049
#endif // HAS_MARLINUI_U8GLIB
20562050

20572051
#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
20582052
#define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens
20592053
//#define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay
2054+
2055+
// Frivolous Game Options
2056+
//#define MARLIN_BRICKOUT
2057+
//#define MARLIN_INVADERS
2058+
//#define MARLIN_SNAKE
2059+
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu
20602060
#endif
20612061

20622062
//

Marlin/src/lcd/dogm/game.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
#include "../../inc/MarlinConfigPre.h"
23+
24+
#if HAS_MARLINUI_U8GLIB && HAS_GAMES
25+
26+
#include "../menu/game/types.h" // includes dogm/game.h
27+
28+
void MarlinGame::frame_start() {
29+
set_color(color::WHITE);
30+
}
31+
32+
void MarlinGame::frame_end() {}
33+
34+
void MarlinGame::set_color(const color color) {
35+
switch (color) {
36+
default:
37+
case color::WHITE: u8g.setColorIndex(1); break;
38+
case color::BLACK: u8g.setColorIndex(0); break;
39+
}
40+
}
41+
42+
void MarlinGame::draw_hline(const game_dim_t x, const game_dim_t y, const game_dim_t w) {
43+
u8g.drawHLine(x, y, w);
44+
}
45+
46+
void MarlinGame::draw_vline(const game_dim_t x, const game_dim_t y, const game_dim_t h) {
47+
u8g.drawVLine(x, y, h);
48+
}
49+
50+
void MarlinGame::draw_frame(const game_dim_t x, const game_dim_t y, const game_dim_t w, const game_dim_t h) {
51+
u8g.drawFrame(x, y, w, h);
52+
}
53+
54+
void MarlinGame::draw_box(const game_dim_t x, const game_dim_t y, const game_dim_t w, const game_dim_t h) {
55+
u8g.drawBox(x, y, w, h);
56+
}
57+
58+
void MarlinGame::draw_pixel(const game_dim_t x, const game_dim_t y) {
59+
u8g.drawPixel(x, y);
60+
}
61+
62+
void MarlinGame::draw_bitmap(const game_dim_t x, const game_dim_t y, const game_dim_t bytes_per_row, const game_dim_t rows, const pgm_bitmap_t bitmap) {
63+
u8g.drawBitmapP(x, y, bytes_per_row, rows, bitmap);
64+
}
65+
66+
int MarlinGame::draw_string(const game_dim_t x, const game_dim_t y, const char* str) {
67+
lcd_moveto(x, y);
68+
return lcd_put_u8str_P(str);
69+
}
70+
71+
int MarlinGame::draw_string(const game_dim_t x, const game_dim_t y, FSTR_P const fstr) {
72+
lcd_moveto(x, y);
73+
return lcd_put_u8str(fstr);
74+
}
75+
76+
void MarlinGame::draw_int(const game_dim_t x, const game_dim_t y, const int value) {
77+
lcd_put_int(x, y, value);
78+
}
79+
80+
#endif // HAS_MARLINUI_U8GLIB && HAS_GAMES

Marlin/src/lcd/dogm/game.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Marlin 3D Printer Firmware
3+
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4+
*
5+
* Based on Sprinter and grbl.
6+
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
#pragma once
23+
24+
#include "marlinui_DOGM.h"
25+
#include "../lcdprint.h"
26+
27+
typedef uint8_t game_dim_t;
28+
typedef const u8g_pgm_uint8_t* pgm_bitmap_t;
29+
30+
constexpr game_dim_t GAME_WIDTH = LCD_PIXEL_WIDTH;
31+
constexpr game_dim_t GAME_HEIGHT = LCD_PIXEL_HEIGHT;
32+
constexpr game_dim_t GAME_FONT_WIDTH = MENU_FONT_WIDTH;
33+
constexpr game_dim_t GAME_FONT_ASCENT = MENU_FONT_ASCENT;

Marlin/src/lcd/e3v2/common/dwin_api.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ void dwinFrameClear(const uint16_t color) {
158158
}
159159

160160
#if DISABLED(TJC_DISPLAY)
161+
161162
// Draw a point
162163
// color: point color
163164
// width: point width 0x01-0x0F
@@ -173,7 +174,67 @@ void dwinFrameClear(const uint16_t color) {
173174
dwinWord(i, y);
174175
dwinSend(i);
175176
}
176-
#endif
177+
178+
// Draw a map of multiple points using minimal amount of point drawing commands
179+
// color: point color
180+
// point_width: point width 0x01-0x0F
181+
// point_height: point height 0x01-0x0F
182+
// x,y: upper left point
183+
// map_columns: columns in theh point map. each column is a byte in the map and contains 8 points
184+
// map_rows: rows in the point map
185+
// map: point bitmap. 2D array of points, 1 bit per point
186+
// Note: somewhat similar to U8G's drawBitmap() function, see https://github.com/olikraus/u8glib/wiki/userreference#drawbitmap
187+
void dwinDrawPointMap(
188+
const uint16_t color,
189+
const uint8_t point_width, const uint8_t point_height,
190+
const uint16_t x, const uint16_t y,
191+
const uint16_t map_columns, const uint16_t map_rows,
192+
const uint8_t *map_data
193+
) {
194+
// At how many bytes should we flush the send buffer?
195+
// One byte is used (hidden) for F_HONE, and we need 4 bytes when appending a point.
196+
// So we should flush the send buffer when we have less than 5 bytes left.
197+
constexpr size_t flush_send_buffer_at = (COUNT(dwinSendBuf) - 1 - 4);
198+
199+
// How long is the header of each draw command?
200+
// => 1B CMD, 2B COLOR, 1B WIDTH, 1B HEIGHT
201+
constexpr size_t command_header_size = 5;
202+
203+
size_t i = 0;
204+
for (uint16_t row = 0; row < map_rows; row++) {
205+
for (uint16_t col = 0; col < map_columns; col++) {
206+
const uint8_t map_byte = map_data[(row * map_columns) + col];
207+
for (uint8_t bit = 0; bit < 8; bit++) {
208+
// Draw a point at this position?
209+
if (TEST(map_byte, bit)) {
210+
// Flush the send buffer and prepare next draw if either
211+
// a) The buffer reached the 'should flush' state, or
212+
// b) This is the first point to draw
213+
if (i >= flush_send_buffer_at || i == 0) {
214+
// Dispatch the current draw command
215+
if (i > command_header_size) dwinSend(i);
216+
217+
// Prepare the next draw command
218+
i = 0;
219+
dwinByte(i, 0x02); // cmd: draw point(s)
220+
dwinWord(i, color);
221+
dwinByte(i, point_width);
222+
dwinByte(i, point_height);
223+
}
224+
225+
// Append point coordinates to draw command
226+
dwinWord(i, x + (point_width * ((8 * col) + (7 - bit)))); // x
227+
dwinWord(i, y + (point_height * (row))); // y
228+
}
229+
}
230+
}
231+
}
232+
233+
// Dispatch final draw command if the buffer contains any points
234+
if (i > command_header_size) dwinSend(i);
235+
}
236+
237+
#endif // !TJC_DISPLAY
177238

178239
// Draw a line
179240
// color: Line segment color

Marlin/src/lcd/e3v2/common/dwin_api.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,24 @@ inline void dwinDrawBox(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t
164164
void dwinDrawPoint(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y);
165165
#endif
166166

167+
// Draw a map of multiple points using minimal amount of point drawing commands
168+
// color: point color
169+
// point_width: point width 0x01-0x0F
170+
// point_height: point height 0x01-0x0F
171+
// x,y: upper left point
172+
// map_columns: columns in theh point map. each column is a byte in the map and contains 8 points
173+
// map_rows: rows in the point map
174+
// map: point bitmap. 2D array of points, 1 bit per point
175+
#if DISABLED(TJC_DISPLAY)
176+
void dwinDrawPointMap(
177+
const uint16_t color,
178+
const uint8_t point_width, const uint8_t point_height,
179+
const uint16_t x, const uint16_t y,
180+
const uint16_t map_columns, const uint16_t map_rows,
181+
const uint8_t *map_data
182+
);
183+
#endif
184+
167185
// Move a screen area
168186
// mode: 0, circle shift; 1, translation
169187
// dir: 0=left, 1=right, 2=up, 3=down

0 commit comments

Comments
 (0)