add more low level drawing functions
This commit is contained in:
@@ -17,16 +17,64 @@
|
|||||||
#include "./fonts/zxpix_font.h"
|
#include "./fonts/zxpix_font.h"
|
||||||
|
|
||||||
LowLevelRenderer::LowLevelRenderer(uint8_t* buffer, int width, int height)
|
LowLevelRenderer::LowLevelRenderer(uint8_t* buffer, int width, int height)
|
||||||
: bit_buffer(buffer), V_WIDTH(width), V_HEIGHT(height), current_font(&font_acme_5_outlines) {}
|
: bit_buffer(buffer), V_WIDTH(width), V_HEIGHT(height), current_font(&font_acme_5_outlines),
|
||||||
|
clipping_enabled(false), clip_x(0), clip_y(0), clip_width(width), clip_height(height) {}
|
||||||
|
|
||||||
void LowLevelRenderer::set_font(const unsigned char (*font)[96][6]) {
|
void LowLevelRenderer::set_font(const unsigned char (*font)[96][6]) {
|
||||||
current_font = font;
|
current_font = font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clipping functions
|
||||||
|
void LowLevelRenderer::set_clip_rect(int x, int y, int width, int height) {
|
||||||
|
clip_x = x;
|
||||||
|
clip_y = y;
|
||||||
|
clip_width = width;
|
||||||
|
clip_height = height;
|
||||||
|
clipping_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LowLevelRenderer::reset_clip_rect() {
|
||||||
|
clipping_enabled = false;
|
||||||
|
clip_x = 0;
|
||||||
|
clip_y = 0;
|
||||||
|
clip_width = V_WIDTH;
|
||||||
|
clip_height = V_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LowLevelRenderer::is_clipping_enabled() const {
|
||||||
|
return clipping_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LowLevelRenderer::is_point_in_clip_rect(int x, int y) {
|
||||||
|
if (!clipping_enabled) return true;
|
||||||
|
return (x >= clip_x && x < clip_x + clip_width &&
|
||||||
|
y >= clip_y && y < clip_y + clip_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer operations
|
||||||
|
void LowLevelRenderer::invert_buffer() {
|
||||||
|
int buffer_size = (V_WIDTH * V_HEIGHT + 7) / 8; // Round up for bit buffer size
|
||||||
|
for (int i = 0; i < buffer_size; ++i) {
|
||||||
|
bit_buffer[i] = ~bit_buffer[i]; // Bitwise NOT to invert all bits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LowLevelRenderer::clear_buffer() {
|
||||||
|
int buffer_size = (V_WIDTH * V_HEIGHT + 7) / 8;
|
||||||
|
for (int i = 0; i < buffer_size; ++i) {
|
||||||
|
bit_buffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LowLevelRenderer::set_pixel(int x, int y, bool on)
|
void LowLevelRenderer::set_pixel(int x, int y, bool on)
|
||||||
{
|
{
|
||||||
if (x < 0 || x >= V_WIDTH || y < 0 || y >= V_HEIGHT)
|
if (x < 0 || x >= V_WIDTH || y < 0 || y >= V_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Check clipping
|
||||||
|
if (!is_point_in_clip_rect(x, y))
|
||||||
|
return;
|
||||||
|
|
||||||
int bit_pos = y * V_WIDTH + x;
|
int bit_pos = y * V_WIDTH + x;
|
||||||
if (on)
|
if (on)
|
||||||
bit_buffer[bit_pos / 8] |= (1 << (7 - (bit_pos % 8)));
|
bit_buffer[bit_pos / 8] |= (1 << (7 - (bit_pos % 8)));
|
||||||
|
|||||||
@@ -33,9 +33,12 @@ private:
|
|||||||
int V_WIDTH;
|
int V_WIDTH;
|
||||||
int V_HEIGHT;
|
int V_HEIGHT;
|
||||||
const unsigned char (*current_font)[96][6];
|
const unsigned char (*current_font)[96][6];
|
||||||
|
bool clipping_enabled;
|
||||||
|
int clip_x, clip_y, clip_width, clip_height;
|
||||||
void draw_corner_arc(int center_x, int center_y, int radius, int quadrant, bool on);
|
void draw_corner_arc(int center_x, int center_y, int radius, int quadrant, bool on);
|
||||||
void fill_bottom_flat_triangle(int x1, int y1, int x2, int y2, int x3, int y3, bool on);
|
void fill_bottom_flat_triangle(int x1, int y1, int x2, int y2, int x3, int y3, bool on);
|
||||||
void fill_top_flat_triangle(int x1, int y1, int x2, int y2, int x3, int y3, bool on);
|
void fill_top_flat_triangle(int x1, int y1, int x2, int y2, int x3, int y3, bool on);
|
||||||
|
bool is_point_in_clip_rect(int x, int y);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LowLevelRenderer(uint8_t* buffer, int width, int height);
|
LowLevelRenderer(uint8_t* buffer, int width, int height);
|
||||||
@@ -56,6 +59,16 @@ public:
|
|||||||
void draw_polygon(const std::vector<std::pair<int, int>>& points, bool on);
|
void draw_polygon(const std::vector<std::pair<int, int>>& points, bool on);
|
||||||
void draw_filled_polygon(const std::vector<std::pair<int, int>>& points, bool on);
|
void draw_filled_polygon(const std::vector<std::pair<int, int>>& points, bool on);
|
||||||
void draw_arc(int center_x, int center_y, int radius, int start_angle, int end_angle, bool on);
|
void draw_arc(int center_x, int center_y, int radius, int start_angle, int end_angle, bool on);
|
||||||
|
|
||||||
|
// Clipping functions
|
||||||
|
void set_clip_rect(int x, int y, int width, int height);
|
||||||
|
void reset_clip_rect();
|
||||||
|
bool is_clipping_enabled() const;
|
||||||
|
|
||||||
|
// Buffer operations
|
||||||
|
void invert_buffer();
|
||||||
|
void clear_buffer();
|
||||||
|
|
||||||
void draw_circle(int x, int y, int radius, bool on);
|
void draw_circle(int x, int y, int radius, bool on);
|
||||||
void draw_filled_circle(int x, int y, int radius, bool on);
|
void draw_filled_circle(int x, int y, int radius, bool on);
|
||||||
void draw_char_vcol(int x, int y, char c);
|
void draw_char_vcol(int x, int y, char c);
|
||||||
|
|||||||
16
main.cpp
16
main.cpp
@@ -36,6 +36,7 @@ int main()
|
|||||||
|
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
bool toggle = false;
|
bool toggle = false;
|
||||||
|
bool inverted = false;
|
||||||
|
|
||||||
while (window.isOpen())
|
while (window.isOpen())
|
||||||
{
|
{
|
||||||
@@ -87,6 +88,14 @@ int main()
|
|||||||
{
|
{
|
||||||
clock.restart();
|
clock.restart();
|
||||||
toggle = !toggle; // Change something every half second
|
toggle = !toggle; // Change something every half second
|
||||||
|
|
||||||
|
// Invert display every 4 seconds (8 cycles)
|
||||||
|
static int cycle_count = 0;
|
||||||
|
cycle_count++;
|
||||||
|
if (cycle_count % 8 == 0) {
|
||||||
|
renderer.invert_buffer();
|
||||||
|
inverted = !inverted;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear buffer
|
// Clear buffer
|
||||||
for (int i = 0; i < sizeof(bit_buffer); i++)
|
for (int i = 0; i < sizeof(bit_buffer); i++)
|
||||||
@@ -131,9 +140,14 @@ int main()
|
|||||||
renderer.draw_line(10, 200, 90, 250, true);
|
renderer.draw_line(10, 200, 90, 250, true);
|
||||||
renderer.draw_line(110, 200, 190, 250, true);
|
renderer.draw_line(110, 200, 190, 250, true);
|
||||||
|
|
||||||
|
// Demonstrate clipping - draw a circle that gets clipped
|
||||||
|
renderer.set_clip_rect(300, 200, 80, 60); // Small rectangle in bottom-right
|
||||||
|
renderer.draw_filled_circle(340, 230, 40, true); // Circle that extends outside clip rect
|
||||||
|
renderer.reset_clip_rect(); // Reset to full screen
|
||||||
|
|
||||||
// Text with different fonts
|
// Text with different fonts
|
||||||
renderer.set_font(&font_acme_5_outlines);
|
renderer.set_font(&font_acme_5_outlines);
|
||||||
renderer.draw_string_scaled(10, 10, "Drawing Demo", 2);
|
renderer.draw_string_scaled(10, 10, inverted ? "INVERTED MODE" : "Drawing Demo", 2);
|
||||||
|
|
||||||
renderer.set_font(&font_5x5);
|
renderer.set_font(&font_5x5);
|
||||||
renderer.draw_string_scaled(10, 270, command_buffer, 1);
|
renderer.draw_string_scaled(10, 270, command_buffer, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user