summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-30 15:02:26 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-30 15:02:26 +0200
commit915dd4b023d0826166d4887100dbed64d46821a9 (patch)
tree7803f23f045e3bf9cb70c7430be3b304212f660f
parentd2af238397ab523b2c1ba7d24875a186b4a8acc6 (diff)
downloadabaos-915dd4b023d0826166d4887100dbed64d46821a9.tar.gz
abaos-915dd4b023d0826166d4887100dbed64d46821a9.tar.bz2
playing with Z buffering in VGA driver
-rw-r--r--src/drivers/video/vga.c21
-rw-r--r--src/drivers/video/vga.h9
-rw-r--r--src/gui/text_widget.c2
-rw-r--r--src/kernel/kernel.c22
4 files changed, 45 insertions, 9 deletions
diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c
index 9d540af..bcd4366 100644
--- a/src/drivers/video/vga.c
+++ b/src/drivers/video/vga.c
@@ -253,7 +253,7 @@ bool vga_set_mode( vga_t *vga, const vga_mode_t mode )
vga->mode = mode;
vga->mode.segment = get_frame_buffer_segment( vga );
- vga->use_z_buffer = false;
+ vga_use_z_buffer( vga, false );
return true;
}
@@ -317,7 +317,7 @@ void vga_set_pixel( vga_t *vga, const int x, const int y, const vga_color_t colo
uint8_t color_idx = get_color_index( color );
- uint8_t *addr = vga->mode.segment + vga->mode.x * y + x;
+ uint8_t *addr = vga->base_addr + vga->mode.x * y + x;
*addr = color_idx;
}
@@ -337,14 +337,14 @@ void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, cons
uint8_t color_idx = get_color_index( color );
for( int yy = y; yy < y + h; yy++ ) {
- uint8_t *addr = vga->mode.segment + vga->mode.x * yy + x;
+ uint8_t *addr = vga->base_addr + vga->mode.x * yy + x;
memset( addr, color_idx, w );
}
}
void vga_clear_screen( vga_t *vga, const vga_color_t color )
{
- memset( vga->mode.segment, get_color_index( color ),
+ memset( vga->base_addr, get_color_index( color ),
vga->mode.x * vga->mode.y );
}
@@ -385,6 +385,19 @@ void vga_wait_for_retrace( vga_t *vga )
void vga_use_z_buffer( vga_t *vga, bool use )
{
vga->use_z_buffer = use;
+
+ if( vga->use_z_buffer ) {
+ vga->base_addr = &vga->zbuffer[0];
+ } else {
+ vga->base_addr = vga->mode.segment;
+ }
}
+void vga_refresh( vga_t *vga )
+{
+ if( vga->use_z_buffer ) {
+ vga_wait_for_retrace( vga );
+ memcpy( vga->mode.segment, vga->zbuffer, 65535 );
+ }
+}
diff --git a/src/drivers/video/vga.h b/src/drivers/video/vga.h
index 0f55f74..d15a55d 100644
--- a/src/drivers/video/vga.h
+++ b/src/drivers/video/vga.h
@@ -43,6 +43,14 @@ typedef struct {
vga_mode_t mode;
void *context;
bool use_z_buffer;
+ // TODO: the Z-buffer should actually be allocated dynamically
+ // depending on the current mode, for now it's a static buffer
+ // able to store the biggest resolution, being planar
+ // 320x200x8 aka 64k
+ uint8_t zbuffer[65535];
+ // stores either the address to the beginning of the segment
+ // (real mapped I/O memory or the beginning of the Z buffer
+ uint8_t *base_addr;
} vga_t;
typedef struct {
@@ -83,5 +91,6 @@ void vga_clear_screen( vga_t *vga, const vga_color_t color );
void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, const vga_color_t background, const vga_color_t foreground );
void vga_wait_for_retrace( vga_t *vga );
void vga_use_z_buffer( vga_t *vga, bool use );
+void vga_refresh( vga_t *vga );
#endif // VGA_H
diff --git a/src/gui/text_widget.c b/src/gui/text_widget.c
index 64bf161..eea2613 100644
--- a/src/gui/text_widget.c
+++ b/src/gui/text_widget.c
@@ -49,7 +49,7 @@ void text_widget_draw( void *obj, graphics_context_t *context )
vga_draw_char( context, *p, x + w, y + h, widget->base.background_color,
VGA_COLOR_WHITE );
w += 9;
- if( w >= widget->base.w - 9 ) {
+ if( w >= widget->base.w - 10 ) {
h += 16;
w = 0;
}
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 197f491..aacfcbd 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -139,7 +139,7 @@ void kernel_main( void )
// for now we are only interested in interrupts,
// so we let the main thread sleep instead of
// burning CPU..
- kernel_halt( );
+// kernel_halt( );
switch( global_context.mode ) {
case MODE_TEXT:
@@ -153,11 +153,13 @@ void kernel_main( void )
// wait for VGA retrace, assume drawing the desktop
// is fast enough to finish in time (so we don't recheck
// for retrace)
- vga_wait_for_retrace( &global_context.vga );
+// vga_wait_for_retrace( &global_context.vga );
// as vga_t is equals to the graphical context for now
((widget_vtable_t *)global_context.desktop.vtable)->draw( &global_context.desktop, &global_context.vga );
+ vga_refresh( &global_context.vga );
+
interrupts_enable( );
break;
@@ -242,14 +244,21 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
}
*p = '\0';
- window_init( &global_context->window3, (widget_t *)&global_context->desktop, 55, 5, vga->mode.x - 65, 100, VGA_COLOR_WHITE );
+ window_init( &global_context->window3, (widget_t *)&global_context->desktop, 55, 5, vga->mode.x - 65, 100, VGA_COLOR_CYAN );
((composite_widget_vtable_t *)global_context->desktop.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window3 );
-// text_widget_init( &global_context->widget3, (widget_t *)&global_context->window3, 1, 1, global_context->window3.base.base.w - 2, global_context->window3.base.base.h - 2, VGA_COLOR_RED, s );
+ text_widget_init( &global_context->widget3, (widget_t *)&global_context->window3, 1, 1, global_context->window3.base.base.w - 2, global_context->window3.base.base.h - 2, VGA_COLOR_RED, s );
// ((composite_widget_vtable_t *)global_context->window3.vtable)->add_child( (composite_widget_t *)&global_context->window3, (widget_t *)&global_context->widget3 );
mouse_set_resolution( mouse, vga->mode.x, vga->mode.y );
}
+
+ // enable Z buffering
+ vga_use_z_buffer( &global_context->vga, true );
+
+ // draw on mode switch
+ ((widget_vtable_t *)global_context->desktop.vtable)->draw( &global_context->desktop, &global_context->vga );
+
global_context->mode = MODE_GRAPHICS;
break;
@@ -325,6 +334,11 @@ static void handle_mouse_event( mouse_event_t *event, void *context )
break;
}
+ // alternative way of redrawing on mouse event
+ // on qemu looses the mouse..
+// interrupts_disable( );
+// ((widget_vtable_t *)desktop->vtable)->draw( &global_context->desktop, &global_context->vga );
+// interrupts_enable( );
break;
}