diff --git a/app b/app index 9862d75..22b3dc5 100755 Binary files a/app and b/app differ diff --git a/low_level_render.cpp b/low_level_render.cpp index 8797470..6952727 100644 --- a/low_level_render.cpp +++ b/low_level_render.cpp @@ -17,16 +17,64 @@ #include "./fonts/zxpix_font.h" 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]) { 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) { if (x < 0 || x >= V_WIDTH || y < 0 || y >= V_HEIGHT) return; + + // Check clipping + if (!is_point_in_clip_rect(x, y)) + return; + int bit_pos = y * V_WIDTH + x; if (on) bit_buffer[bit_pos / 8] |= (1 << (7 - (bit_pos % 8))); diff --git a/low_level_render.h b/low_level_render.h index 6cb19ab..8331425 100644 --- a/low_level_render.h +++ b/low_level_render.h @@ -33,9 +33,12 @@ private: int V_WIDTH; int V_HEIGHT; 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 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); + bool is_point_in_clip_rect(int x, int y); public: LowLevelRenderer(uint8_t* buffer, int width, int height); @@ -56,6 +59,16 @@ public: void draw_polygon(const std::vector>& points, bool on); void draw_filled_polygon(const std::vector>& points, 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_filled_circle(int x, int y, int radius, bool on); void draw_char_vcol(int x, int y, char c); diff --git a/main.cpp b/main.cpp index 7b4e961..40345a1 100644 --- a/main.cpp +++ b/main.cpp @@ -36,6 +36,7 @@ int main() sf::Clock clock; bool toggle = false; + bool inverted = false; while (window.isOpen()) { @@ -87,6 +88,14 @@ int main() { clock.restart(); 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 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(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 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.draw_string_scaled(10, 270, command_buffer, 1);