import
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
*.o
|
||||||
|
ufb-test
|
||||||
|
.idea/
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.PHONY: build run
|
||||||
|
|
||||||
|
build: ufb-test
|
||||||
|
|
||||||
|
run: build
|
||||||
|
./ufb-test
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f ufb-test
|
||||||
|
|
||||||
|
ufb-test: main.c framebuffer.c framebuffer.h framebuffer_config.h
|
||||||
|
cc -o $@ $^ -I.
|
||||||
+282
@@ -0,0 +1,282 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2022/11/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "framebuffer.h"
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a)>(b)?(b):(a))
|
||||||
|
#define MAX(a, b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
uint8_t fb[(FBH / 8) * FBW];
|
||||||
|
|
||||||
|
/** Fill with a vertical pattern, 1 byte */
|
||||||
|
void fb_fill(uint8_t pattern)
|
||||||
|
{
|
||||||
|
memset(fb, pattern, sizeof(fb));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_mask(fbsize_t idx, uint8_t mask, uint8_t color)
|
||||||
|
{
|
||||||
|
if (color != 0) {
|
||||||
|
fb[idx] |= mask;
|
||||||
|
} else {
|
||||||
|
fb[idx] &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_px(fbpos_t x, fbpos_t y, uint8_t color)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return; }
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
draw_mask(cell, 1 << rowrem, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t fb_getpx(fbpos_t x, fbpos_t y)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return 0; }
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
if (fb[cell] & (1 << rowrem)) {
|
||||||
|
return 0xFF;
|
||||||
|
} else {
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, uint8_t color)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return; }
|
||||||
|
w = MIN(FBW - x, w);
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
for (uint8_t i = 0; i < w; i++) {
|
||||||
|
draw_mask(cell, 1 << rowrem, color);
|
||||||
|
cell++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, uint8_t color)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return; }
|
||||||
|
h = MIN(FBH - y - 1, h);
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
|
||||||
|
|
||||||
|
if (rowrem + h < 8) {
|
||||||
|
// all within one cell
|
||||||
|
const uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
|
||||||
|
draw_mask(cell, mask, color);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// First
|
||||||
|
draw_mask(cell, 0xFF << rowrem, color);
|
||||||
|
h -= (rowrem == 0 ? 8 : (8 - rowrem));
|
||||||
|
|
||||||
|
const fbpos_t whole_cells = h / 8;
|
||||||
|
if (whole_cells > 0) {
|
||||||
|
h -= whole_cells * 8;
|
||||||
|
for (fbpos_t i = 0; i < whole_cells; i++) {
|
||||||
|
cell += FBW;
|
||||||
|
draw_mask(cell, 0xFF, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// last
|
||||||
|
cell += FBW;
|
||||||
|
draw_mask(cell, 0xFF >> (8 - h), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, uint8_t color)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return; }
|
||||||
|
w = MIN(FBW - x, w);
|
||||||
|
h = MIN(FBH - y, h);
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
|
||||||
|
if (w == 1 && h == 1) {
|
||||||
|
fb_px(x, y, color);
|
||||||
|
} else if (w == 1) {
|
||||||
|
fb_vline(x, y, h, color);
|
||||||
|
} else if (h == 1) {
|
||||||
|
fb_hline(x, y, w, color);
|
||||||
|
} else if (rowrem + h <= 8) {
|
||||||
|
// all within one cell
|
||||||
|
uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
|
||||||
|
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// First
|
||||||
|
uint8_t mask = (0xFF << rowrem);
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
h -= 8 - rowrem;
|
||||||
|
|
||||||
|
const fbpos_t whole_cells = h / 8;
|
||||||
|
if (whole_cells > 0) {
|
||||||
|
h -= whole_cells * 8;
|
||||||
|
for (fbpos_t j = 0; j < whole_cells; j++) {
|
||||||
|
cell += FBW;
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
draw_mask(cell + i, 0xFF, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cell += FBW;
|
||||||
|
|
||||||
|
// last
|
||||||
|
mask = (0xFF >> (8 - h));
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_frame(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t thickness, uint8_t color)
|
||||||
|
{
|
||||||
|
if (thickness == 0) {
|
||||||
|
return;
|
||||||
|
} else if (thickness == 1) {
|
||||||
|
fb_hline(x, y, w, color);
|
||||||
|
fb_vline(x, y, h, color);
|
||||||
|
fb_hline(x, y + h - 1, w, color);
|
||||||
|
fb_vline(x + w - 1, y, h, color);
|
||||||
|
} else {
|
||||||
|
fb_rect(x, y, w, thickness, color);
|
||||||
|
fb_rect(x, y + h - thickness, w, thickness, color);
|
||||||
|
fb_rect(x, y + thickness, thickness, h - 2 * thickness, color);
|
||||||
|
fb_rect(x + w - thickness, y + thickness, thickness, h - 2 * thickness, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_bitmap(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, uint8_t color)
|
||||||
|
{
|
||||||
|
if (x >= FBW || y >= FBH) { return; }
|
||||||
|
const fbpos_t w0 = w;
|
||||||
|
w = MIN(FBW - x - 1, w);
|
||||||
|
h = MIN(FBH - y - 1, h);
|
||||||
|
const fbpos_t row = y / 8;
|
||||||
|
const fbpos_t rowrem = y % 8;
|
||||||
|
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
|
||||||
|
if (rowrem + h <= 8) {
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
// all within one cell
|
||||||
|
const uint8_t mask = (map[i] & (0xFF >> (8 - h))) << rowrem;
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
fbsize_t mapc0 = 0;
|
||||||
|
|
||||||
|
// Draw the bitmap slice-by-slice based on how rows of the bitmap intersect with rows of the canvas.
|
||||||
|
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
|
||||||
|
while (h > 0) {
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
const uint8_t mask = (map[i + mapc0] & (0xFF >> rowrem)) << rowrem;
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell += FBW;
|
||||||
|
|
||||||
|
if (rowrem != 0) {
|
||||||
|
for (fbpos_t i = 0; i < w; i++) {
|
||||||
|
const uint8_t mask = (map[i + mapc0] & (0xFF << (8 - rowrem))) >> (8 - rowrem);
|
||||||
|
draw_mask(cell + i, mask, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h > 8) {
|
||||||
|
h -= 8;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mapc0 += w0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum SevenSegBars {
|
||||||
|
T = 1, RT = 2, RB = 4, B = 8, LB = 16, LT = 32, M = 64
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t PROGMEM seven[] = {
|
||||||
|
[0] = T | RT | RB | B | LB | LT,
|
||||||
|
[1] = RT | RB,
|
||||||
|
[2] = T | RT | M | LB | B,
|
||||||
|
[3] = T | RT | M | RB | B,
|
||||||
|
[4] = RT | RB | M | LT,
|
||||||
|
[5] = T | LT | M | RB | B,
|
||||||
|
[6] = T | LT | LB | B | RB | M,
|
||||||
|
[7] = T | RT | RB,
|
||||||
|
[8] = T | LT | RT | LB | RB | B | M,
|
||||||
|
[9] = T | LT | RT | RB | B | M,
|
||||||
|
};
|
||||||
|
|
||||||
|
fbpos_t fb_7seg_dig(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t digit, uint8_t color)
|
||||||
|
{
|
||||||
|
const uint8_t mask = digit > 9 ? 0 : pgm_read_byte(&seven[digit]);
|
||||||
|
const fbpos_t wi = w - th * 2;
|
||||||
|
const fbpos_t hi = (h - th * 3) / 2;
|
||||||
|
|
||||||
|
bool bcolor = !color; // changed for XOR
|
||||||
|
|
||||||
|
fb_rect(x + th,
|
||||||
|
y,
|
||||||
|
wi,
|
||||||
|
th, bcolor ^ (bool) (mask & T));
|
||||||
|
|
||||||
|
fb_rect(x + th,
|
||||||
|
y + th + hi,
|
||||||
|
wi,
|
||||||
|
th, bcolor ^ (bool) (mask & M));
|
||||||
|
|
||||||
|
fb_rect(x + th,
|
||||||
|
y + th * 2 + hi * 2,
|
||||||
|
wi,
|
||||||
|
th, bcolor ^ (bool) (mask & B));
|
||||||
|
|
||||||
|
fb_rect(x,
|
||||||
|
y + th,
|
||||||
|
th,
|
||||||
|
hi, bcolor ^ (bool) (mask & LT));
|
||||||
|
|
||||||
|
fb_rect(x + th + wi,
|
||||||
|
y + hi + th,
|
||||||
|
th,
|
||||||
|
hi, bcolor ^ (bool) (mask & LB));
|
||||||
|
|
||||||
|
fb_rect(x + th + wi,
|
||||||
|
y + th,
|
||||||
|
th,
|
||||||
|
hi, bcolor ^ (bool) (mask & RT));
|
||||||
|
|
||||||
|
fb_rect(x + th + wi,
|
||||||
|
y + th * 2 + hi,
|
||||||
|
th,
|
||||||
|
hi, bcolor ^ (bool) (mask & RB));
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
fbpos_t fb_7seg_period(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t color)
|
||||||
|
{
|
||||||
|
const fbpos_t hi = (h - th * 3) / 2;
|
||||||
|
fb_rect(x, y + hi * 2 + th * 2, th, th, color);
|
||||||
|
return th;
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2022/11/12.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FRAMEBUFFER_H
|
||||||
|
#define FRAMEBUFFER_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "framebuffer_config.h"
|
||||||
|
|
||||||
|
#define FBSET 0xFF
|
||||||
|
#define FBCLEAR 0x00
|
||||||
|
|
||||||
|
typedef uint16_t fbsize_t;
|
||||||
|
typedef uint8_t fbpos_t;
|
||||||
|
|
||||||
|
/// Framebuffer backing array.
|
||||||
|
///
|
||||||
|
/// The format is the native format for SSD1306: array of bytes representing pixels in 8 rows at once, LSB is the topmost row.
|
||||||
|
///
|
||||||
|
/// a0 b0 ... til the display width
|
||||||
|
/// a1 b1
|
||||||
|
/// a2 b2
|
||||||
|
/// ... ...
|
||||||
|
/// a7 b7
|
||||||
|
///
|
||||||
|
/// and more bytes continue rows 8-15 and so on
|
||||||
|
extern uint8_t fb[(FBH / 8) * FBW];
|
||||||
|
|
||||||
|
/// Fill the entire screen with a byte pattern.
|
||||||
|
/// Use 0xFF or 0x00 for a solid fill. Other patterns may be used to create horizontal stripes.
|
||||||
|
void fb_fill(uint8_t pattern);
|
||||||
|
|
||||||
|
/// Clear the display (fill with 0x00)
|
||||||
|
static inline void fb_clear(void)
|
||||||
|
{
|
||||||
|
fb_fill(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a single pixel
|
||||||
|
void fb_px(fbpos_t x, fbpos_t y, uint8_t color);
|
||||||
|
|
||||||
|
/// Get pixel color
|
||||||
|
uint8_t fb_getpx(fbpos_t x, fbpos_t y);
|
||||||
|
|
||||||
|
/// Draw a horizontal line
|
||||||
|
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a vertical line
|
||||||
|
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a filled rect
|
||||||
|
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a frame (unfilled rect)
|
||||||
|
void fb_frame(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t thickness, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a bitmap
|
||||||
|
void fb_bitmap(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a 7-segment digit. Returns its width (without spacing)
|
||||||
|
///
|
||||||
|
/// \param x - pos X (left top)
|
||||||
|
/// \param y - pos Y (left top)
|
||||||
|
/// \param w - full digit width
|
||||||
|
/// \param h - full digit height; will be adjusted down if needed
|
||||||
|
/// \param th - thickness
|
||||||
|
/// \param digit - digit 0-9
|
||||||
|
/// \return width taken
|
||||||
|
fbpos_t fb_7seg_dig(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t digit, uint8_t color);
|
||||||
|
|
||||||
|
/// Draw a 7-segment period. Returns its width (without spacing).
|
||||||
|
/// Digit height is (w * 2 - th)
|
||||||
|
///
|
||||||
|
/// \param x - pos X (digit left top)
|
||||||
|
/// \param y - pos Y (digit left top)
|
||||||
|
/// \param w - full digit width
|
||||||
|
/// \param h - full digit height; will be adjusted down if needed
|
||||||
|
/// \param th - thickness
|
||||||
|
/// \return width taken
|
||||||
|
fbpos_t fb_7seg_period(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t color);
|
||||||
|
|
||||||
|
/// Output the framebuffer array `fb` to the display device.
|
||||||
|
///
|
||||||
|
/// The user must implement this
|
||||||
|
extern void fb_blit(void);
|
||||||
|
|
||||||
|
#endif //FRAMEBUFFER_H
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef FRAMEBUFFER_CONFIG_H
|
||||||
|
#define FRAMEBUFFER_CONFIG_H
|
||||||
|
|
||||||
|
/* Tiny framebuffer */
|
||||||
|
#define FBW 48
|
||||||
|
#define FBH 32
|
||||||
|
|
||||||
|
// if built for AVR, uncommend the include and comment the fake defines:
|
||||||
|
// #include <avr/pgmspace.h>
|
||||||
|
#define PROGMEM
|
||||||
|
#define pgm_read_byte(adr) (*adr)
|
||||||
|
|
||||||
|
#endif /* FRAMEBUFFER_CONFIG_H */
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "framebuffer.h"
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
fb_clear();
|
||||||
|
|
||||||
|
|
||||||
|
const uint8_t ryba[14] = {
|
||||||
|
0b11000011,
|
||||||
|
0b01100110,
|
||||||
|
0b01111110,
|
||||||
|
0b00111100,
|
||||||
|
0b00011000,
|
||||||
|
0b00111100,
|
||||||
|
0b01111110,
|
||||||
|
0b11111111,
|
||||||
|
0b11111111,
|
||||||
|
0b11111011,
|
||||||
|
0b11111111,
|
||||||
|
0b01111110,
|
||||||
|
0b00111100,
|
||||||
|
0b00011000,
|
||||||
|
};
|
||||||
|
#define ZIR_W 12
|
||||||
|
#define ZIR_H 24
|
||||||
|
const uint8_t zirafa[(ZIR_H/8) * ZIR_W] = {
|
||||||
|
// levo
|
||||||
|
0b10000000,
|
||||||
|
0b01000000,
|
||||||
|
0b00100000,
|
||||||
|
0b00010000,
|
||||||
|
0b00001000,
|
||||||
|
0b00000100,
|
||||||
|
0b00000010,
|
||||||
|
0b00011001,
|
||||||
|
0b00011111,
|
||||||
|
0b11111000,
|
||||||
|
0b00011111,
|
||||||
|
0b00001000,
|
||||||
|
//
|
||||||
|
0b10000000,
|
||||||
|
0b01000000,
|
||||||
|
0b00100000,
|
||||||
|
0b00010000,
|
||||||
|
0b00001000,
|
||||||
|
0b00000100,
|
||||||
|
0b00000010,
|
||||||
|
0b00000001,
|
||||||
|
0b10000000,
|
||||||
|
0b11111111,
|
||||||
|
0b00100000,
|
||||||
|
0b00010000,
|
||||||
|
//
|
||||||
|
0b00110000,
|
||||||
|
0b10001000,
|
||||||
|
0b11111000,
|
||||||
|
0b00011000,
|
||||||
|
0b11111000,
|
||||||
|
0b10011000,
|
||||||
|
0b00011000,
|
||||||
|
0b10011000,
|
||||||
|
0b11111000,
|
||||||
|
0b00011111,
|
||||||
|
0b11111000,
|
||||||
|
0b10000000,
|
||||||
|
};
|
||||||
|
|
||||||
|
//fb_bitmap(0, pos, 14, 8, ryba, 1);
|
||||||
|
|
||||||
|
// fb_bitmap(0, 0, ZIR_W, ZIR_H, zirafa, 1);
|
||||||
|
// fb_bitmap(ZIR_W+2, 12, ZIR_W, ZIR_H, zirafa, 1);
|
||||||
|
// fb_bitmap((ZIR_W + 2) * 2, 2, ZIR_W, ZIR_H, zirafa, 1);
|
||||||
|
|
||||||
|
fb_frame(0, 0, 48, 32, 2, 1);
|
||||||
|
|
||||||
|
uint8_t x = 3;
|
||||||
|
uint8_t w = 7;
|
||||||
|
uint8_t h = 10;
|
||||||
|
uint8_t th = 1;
|
||||||
|
uint8_t sp = 3;
|
||||||
|
x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 7, /*color*/ 1) + sp;
|
||||||
|
x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 9, /*color*/ 1) + sp;
|
||||||
|
x += fb_7seg_period(x, 3, w, h, th, /*color*/ 1) + sp;
|
||||||
|
x += fb_7seg_dig(x, 3, w, h, th, /*val*/ 5, /*color*/ 1) + sp;
|
||||||
|
|
||||||
|
//fb_frame(10, 7, 20, 20, 2, 1);
|
||||||
|
|
||||||
|
fb_blit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void fb_blit() {
|
||||||
|
for(int y = 0; y < FBH; y++) {
|
||||||
|
for(int x = 0; x < FBW; x++) {
|
||||||
|
bool b = fb[(y/8)*FBW + x] & (1 << (y%8));
|
||||||
|
if (b) {
|
||||||
|
printf("\x1b[1;32m#\x1b[m");
|
||||||
|
} else {
|
||||||
|
if (y%8 == 0) {
|
||||||
|
printf("\x1b[34m.\x1b[m");
|
||||||
|
} else {
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user