Skip to content

Commit

Permalink
✨ Games for E3V2 + MarlinUI (#27620)
Browse files Browse the repository at this point in the history
  • Loading branch information
shadow578 authored Jan 9, 2025
1 parent de76f2f commit 22977c8
Show file tree
Hide file tree
Showing 15 changed files with 808 additions and 94 deletions.
12 changes: 6 additions & 6 deletions Marlin/Configuration_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2035,17 +2035,17 @@
//#define STATUS_HEAT_PERCENT // Show heating in a progress bar
//#define STATUS_HEAT_POWER // Show heater output power as a vertical bar

// Frivolous Game Options
//#define MARLIN_BRICKOUT
//#define MARLIN_INVADERS
//#define MARLIN_SNAKE
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu

#endif // HAS_MARLINUI_U8GLIB

#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
#define MENU_HOLLOW_FRAME // Enable to save many cycles by drawing a hollow frame on Menu Screens
//#define OVERLAY_GFX_REVERSE // Swap the CW/CCW indicators in the graphics overlay

// Frivolous Game Options
//#define MARLIN_BRICKOUT
//#define MARLIN_INVADERS
//#define MARLIN_SNAKE
//#define GAMES_EASTER_EGG // Add extra blank lines above the "Games" sub-menu
#endif

//
Expand Down
80 changes: 80 additions & 0 deletions Marlin/src/lcd/dogm/game.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfigPre.h"

#if HAS_MARLINUI_U8GLIB && HAS_GAMES

#include "../menu/game/types.h" // includes dogm/game.h

void MarlinGame::frame_start() {
set_color(color::WHITE);
}

void MarlinGame::frame_end() {}

void MarlinGame::set_color(const color color) {
switch (color) {
default:
case color::WHITE: u8g.setColorIndex(1); break;
case color::BLACK: u8g.setColorIndex(0); break;
}
}

void MarlinGame::draw_hline(const game_dim_t x, const game_dim_t y, const game_dim_t w) {
u8g.drawHLine(x, y, w);
}

void MarlinGame::draw_vline(const game_dim_t x, const game_dim_t y, const game_dim_t h) {
u8g.drawVLine(x, y, h);
}

void MarlinGame::draw_frame(const game_dim_t x, const game_dim_t y, const game_dim_t w, const game_dim_t h) {
u8g.drawFrame(x, y, w, h);
}

void MarlinGame::draw_box(const game_dim_t x, const game_dim_t y, const game_dim_t w, const game_dim_t h) {
u8g.drawBox(x, y, w, h);
}

void MarlinGame::draw_pixel(const game_dim_t x, const game_dim_t y) {
u8g.drawPixel(x, y);
}

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) {
u8g.drawBitmapP(x, y, bytes_per_row, rows, bitmap);
}

int MarlinGame::draw_string(const game_dim_t x, const game_dim_t y, const char* str) {
lcd_moveto(x, y);
return lcd_put_u8str_P(str);
}

int MarlinGame::draw_string(const game_dim_t x, const game_dim_t y, FSTR_P const fstr) {
lcd_moveto(x, y);
return lcd_put_u8str(fstr);
}

void MarlinGame::draw_int(const game_dim_t x, const game_dim_t y, const int value) {
lcd_put_int(x, y, value);
}

#endif // HAS_MARLINUI_U8GLIB && HAS_GAMES
33 changes: 33 additions & 0 deletions Marlin/src/lcd/dogm/game.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2025 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once

#include "marlinui_DOGM.h"
#include "../lcdprint.h"

typedef uint8_t game_dim_t;
typedef const u8g_pgm_uint8_t* pgm_bitmap_t;

constexpr game_dim_t GAME_WIDTH = LCD_PIXEL_WIDTH;
constexpr game_dim_t GAME_HEIGHT = LCD_PIXEL_HEIGHT;
constexpr game_dim_t GAME_FONT_WIDTH = MENU_FONT_WIDTH;
constexpr game_dim_t GAME_FONT_ASCENT = MENU_FONT_ASCENT;
63 changes: 62 additions & 1 deletion Marlin/src/lcd/e3v2/common/dwin_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ void dwinFrameClear(const uint16_t color) {
}

#if DISABLED(TJC_DISPLAY)

// Draw a point
// color: point color
// width: point width 0x01-0x0F
Expand All @@ -173,7 +174,67 @@ void dwinFrameClear(const uint16_t color) {
dwinWord(i, y);
dwinSend(i);
}
#endif

// Draw a map of multiple points using minimal amount of point drawing commands
// color: point color
// point_width: point width 0x01-0x0F
// point_height: point height 0x01-0x0F
// x,y: upper left point
// map_columns: columns in theh point map. each column is a byte in the map and contains 8 points
// map_rows: rows in the point map
// map: point bitmap. 2D array of points, 1 bit per point
// Note: somewhat similar to U8G's drawBitmap() function, see https://github.com/olikraus/u8glib/wiki/userreference#drawbitmap
void dwinDrawPointMap(
const uint16_t color,
const uint8_t point_width, const uint8_t point_height,
const uint16_t x, const uint16_t y,
const uint16_t map_columns, const uint16_t map_rows,
const uint8_t *map_data
) {
// At how many bytes should we flush the send buffer?
// One byte is used (hidden) for F_HONE, and we need 4 bytes when appending a point.
// So we should flush the send buffer when we have less than 5 bytes left.
constexpr size_t flush_send_buffer_at = (COUNT(dwinSendBuf) - 1 - 4);

// How long is the header of each draw command?
// => 1B CMD, 2B COLOR, 1B WIDTH, 1B HEIGHT
constexpr size_t command_header_size = 5;

size_t i = 0;
for (uint16_t row = 0; row < map_rows; row++) {
for (uint16_t col = 0; col < map_columns; col++) {
const uint8_t map_byte = map_data[(row * map_columns) + col];
for (uint8_t bit = 0; bit < 8; bit++) {
// Draw a point at this position?
if (TEST(map_byte, bit)) {
// Flush the send buffer and prepare next draw if either
// a) The buffer reached the 'should flush' state, or
// b) This is the first point to draw
if (i >= flush_send_buffer_at || i == 0) {
// Dispatch the current draw command
if (i > command_header_size) dwinSend(i);

// Prepare the next draw command
i = 0;
dwinByte(i, 0x02); // cmd: draw point(s)
dwinWord(i, color);
dwinByte(i, point_width);
dwinByte(i, point_height);
}

// Append point coordinates to draw command
dwinWord(i, x + (point_width * ((8 * col) + (7 - bit)))); // x
dwinWord(i, y + (point_height * (row))); // y
}
}
}
}

// Dispatch final draw command if the buffer contains any points
if (i > command_header_size) dwinSend(i);
}

#endif // !TJC_DISPLAY

// Draw a line
// color: Line segment color
Expand Down
18 changes: 18 additions & 0 deletions Marlin/src/lcd/e3v2/common/dwin_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,24 @@ inline void dwinDrawBox(uint8_t mode, uint16_t color, uint16_t xStart, uint16_t
void dwinDrawPoint(uint16_t color, uint8_t width, uint8_t height, uint16_t x, uint16_t y);
#endif

// Draw a map of multiple points using minimal amount of point drawing commands
// color: point color
// point_width: point width 0x01-0x0F
// point_height: point height 0x01-0x0F
// x,y: upper left point
// map_columns: columns in theh point map. each column is a byte in the map and contains 8 points
// map_rows: rows in the point map
// map: point bitmap. 2D array of points, 1 bit per point
#if DISABLED(TJC_DISPLAY)
void dwinDrawPointMap(
const uint16_t color,
const uint8_t point_width, const uint8_t point_height,
const uint16_t x, const uint16_t y,
const uint16_t map_columns, const uint16_t map_rows,
const uint8_t *map_data
);
#endif

// Move a screen area
// mode: 0, circle shift; 1, translation
// dir: 0=left, 1=right, 2=up, 3=down
Expand Down
Loading

0 comments on commit 22977c8

Please sign in to comment.