diff options
Diffstat (limited to 'src/drivers/video/vga.c')
-rw-r--r-- | src/drivers/video/vga.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c index 75e96e6..456e539 100644 --- a/src/drivers/video/vga.c +++ b/src/drivers/video/vga.c @@ -20,7 +20,14 @@ static vga_vtable_t const vga_vtable = { video_register_mode, video_supports_mode, video_set_mode, - vga_switch_mode + vga_switch_mode, + vga_set_pixel, + vga_draw_rectangle, + vga_clear_screen, + vga_draw_char, + vga_wait_for_retrace, + vga_use_z_buffer, + vga_refresh } }; @@ -252,9 +259,9 @@ bool vga_switch_mode( void *obj, const video_mode_t *mode ) write_registers( vga, vga_mode->regs ); - vga->mode = (vga_mode_t *)mode; - vga->mode->segment = get_frame_buffer_segment( vga ); - vga->mode->segment_size = get_frame_buffer_segment_size( vga ); + vga_mode->segment = get_frame_buffer_segment( vga ); + vga_mode->segment_size = get_frame_buffer_segment_size( vga ); + vga->base.mode = mode; vga_use_z_buffer( vga, false ); @@ -291,55 +298,62 @@ static uint8_t get_color_index( const video_rgb_color_t c ) static bool params_ok( vga_t *vga, const int x, const int y ) { - if( x < 0 || x > vga->mode->base.x || y < 0 || y > vga->mode->base.y ) { + if( x < 0 || x > vga->base.mode->x || y < 0 || y > vga->base.mode->y ) { return false; } return true; } -void vga_set_pixel( vga_t *vga, const int x, const int y, const video_rgb_color_t color ) +void vga_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + if( !params_ok( vga, x, y ) ) { kernel_panic( "Pixel coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x, y, vga->mode->base.x, vga->mode->base.y ); + x, y, vga->base.mode->x, vga->base.mode->y ); } uint8_t color_idx = get_color_index( color ); - uint8_t *addr = vga->base_addr + vga->mode->base.x * y + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * y + x; *addr = color_idx; } -void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, const int h, const video_rgb_color_t color ) +void vga_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + if( !params_ok( vga, x, y ) ) { kernel_panic( "Rectangle start coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x, y, vga->mode->base.x, vga->mode->base.y ); + x, y, vga->base.mode->x, vga->base.mode->y ); } if( !params_ok( vga, x + w, y + h ) ) { kernel_panic( "Rectangle end coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)", - x + w, y + h, vga->mode->base.x, vga->mode->base.y ); + x + w, y + h, vga->base.mode->x, vga->base.mode->y ); } uint8_t color_idx = get_color_index( color ); for( int yy = y; yy < y + h; yy++ ) { - uint8_t *addr = vga->base_addr + vga->mode->base.x * yy + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * yy + x; memset( addr, color_idx, w ); } } -void vga_clear_screen( vga_t *vga, const video_rgb_color_t color ) +void vga_clear_screen( void *obj, const video_rgb_color_t color ) { + vga_t *vga = (vga_t *)obj; + memset( vga->base_addr, get_color_index( color ), - vga->mode->base.x * vga->mode->base.y ); + vga->base.mode->x * vga->base.mode->y ); } -void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ) +void vga_draw_char( void *obj, const unsigned char c, const int x, const int y, const video_rgb_color_t background, const video_rgb_color_t foreground ) { + vga_t *vga = (vga_t *)obj; //const struct bitmap_font font = { @@ -367,42 +381,44 @@ void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y, data[vga_font.Width-1-xx] = fg_color_idx; } } - uint8_t *addr = vga->base_addr + vga->mode->base.x * ( y + yy ) + x; + uint8_t *addr = vga->base_addr + vga->base.mode->x * ( y + yy ) + x; memcpy( addr, data, vga_font.Width ); } } -void vga_wait_for_retrace( vga_t *vga ) +void vga_wait_for_retrace( void *obj ) { + vga_t *vga = (vga_t *)obj; + while( port8_read( &vga->attribute_controller_reset_port ) & 0x08 ); while( !( port8_read( &vga->attribute_controller_reset_port ) & 0x08 ) ); } -void vga_use_z_buffer( vga_t *vga, bool use ) +void vga_use_z_buffer( void *obj, bool use ) { - if( vga->use_z_buffer == use ) { - return; - } - + vga_t *vga = (vga_t *)obj; + vga->use_z_buffer = use; if( vga->use_z_buffer ) { - vga->zbuffer = (uint8_t *)malloc( vga->mode->segment_size ); + vga->zbuffer = (uint8_t *)malloc( ((vga_mode_t *)(vga->base.mode))->segment_size ); vga->base_addr = &vga->zbuffer[0]; } else { if( vga->zbuffer != NULL ) { free( vga->zbuffer ); vga->zbuffer = NULL; } - vga->base_addr = vga->mode->segment; + vga->base_addr = ((vga_mode_t *)(vga->base.mode))->segment; } } -void vga_refresh( vga_t *vga ) +void vga_refresh( void *obj ) { + vga_t *vga = (vga_t *)obj; + if( vga->use_z_buffer ) { vga_wait_for_retrace( vga ); - memcpy( vga->mode->segment, vga->zbuffer, vga->mode->segment_size ); + memcpy( ((vga_mode_t *)(vga->base.mode))->segment, vga->zbuffer, ((vga_mode_t *)(vga->base.mode))->segment_size ); } } |