summaryrefslogtreecommitdiff
path: root/src/drivers/video/video.c
blob: 616971407b997e510d5b91c12831b33a8a99d9bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "video.h"

#include "string.h"
#include "kernel.h"

#undef DEBUG

static video_vtable_t const video_vtable = {
	{
	driver_activate,
	driver_deactivate,
	driver_deinit,
	driver_print_name,
	driver_print_info
	}
};

void video_init( video_t *video, interrupt_t *interrupt, void *context )
{
	memset( video, 0, sizeof( video_t ) );

	driver_init( (driver_t *)video, DRIVER_TYPE_VIDEO, interrupt, context );

	video->nof_modes = 0;

	((driver_t *)video)->vtable = (driver_vtable_t *)&video_vtable;
}

video_mode_t video_make_mode( const video_mode_type_t mode_type, const int x, const int y, const int color_depth )
{
	video_mode_t mode;

	mode.mode_type = mode_type;
	mode.x = x;
	mode.y = y;
	mode.color_depth = color_depth;

	return mode;
}

void video_register_mode( void *obj, const video_mode_t *mode )
{
	video_t *video = (video_t *)obj;

	if( video->nof_modes >= MAX_NOF_VIDEO_MODES ) {
		kernel_panic( "Trying to register too many video modes, see MAX_NOF_VIDEO_MODES: %d", MAX_NOF_VIDEO_MODES );
	}

	video->modes[video->nof_modes++] = mode;
}

static int get_matching_mode_idx( video_t *video, const video_mode_t mode )
{
	for( int i = 0; video->modes[i]->x != 0; i++ ) {
		if( 	mode.mode_type == video->modes[i]->mode_type &&
			mode.x == video->modes[i]->x &&
			mode.y == video->modes[i]->y &&
			mode.color_depth == video->modes[i]->color_depth ) {
			return i;
		}
	}

	return -1;
}

bool video_supports_mode( void *obj, const video_mode_t mode )
{
	video_t *video = (video_t *)obj;

	for( int i = 0; video->modes[i]->x != 0; i++ ) {
		if( 	mode.mode_type == video->modes[i]->mode_type &&
			mode.x == video->modes[i]->x &&
			mode.y == video->modes[i]->y &&
			mode.color_depth == video->modes[i]->color_depth ) {
			return true;
		}
	}

	return false;
}

bool video_set_mode( void *obj, const video_mode_t mode )
{
	video_t *video = (video_t *)obj;

	// do not allow unknown timings!
	if( !((video_vtable_t *)(video->base.vtable))->supports_mode( obj, mode ) ) {
		return false;
	}

	const video_mode_t *matching_mode = video->modes[get_matching_mode_idx( video, mode )];

	return ((video_vtable_t *)(video->base.vtable))->switch_mode( obj, matching_mode );
}

bool video_switch_mode( void *obj, const video_mode_t *mode )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 

	return false;
}

video_rgb_color_t video_make_rgb_color( const int R, const int G, const int B )
{
	video_rgb_color_t c;

	c.R = R;
	c.G = G;
	c.B = B;

	return c;
}

const video_rgb_color_t VIDEO_RGB_COLOR_BLACK 		= { 0x00, 0x00, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_BLUE 		= { 0x00, 0x00, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_GREEN 		= { 0x00, 0xAA, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_CYAN 		= { 0x00, 0xAA, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_RED 		= { 0xAA, 0x00, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_MAGENTA 	= { 0xAA, 0x00, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_BROWN 		= { 0xAA, 0x55, 0x00 };
const video_rgb_color_t VIDEO_RGB_COLOR_GRAY	 	= { 0xAA, 0xAA, 0xAA };
const video_rgb_color_t VIDEO_RGB_COLOR_WHITE 		= { 0xFF, 0xFF, 0xFF };

/*
0x8 	0x38 	21,21,21 	85,85,85 	#555555 	dark gray
0x9 	0x39 	21,21,63 	85,85,255 	#5555ff 	bright blue
0xA 	0x3A 	21,63,21 	85,255,85 	#55ff55 	bright green
0xB 	0x3B 	21,63,63 	85,255,255 	#55ffff 	bright cyan
0xC 	0x3C 	63,21,21 	255,85,85 	#ff5555 	bright red
0xD 	0X3D 	63,21,63 	255,85,255 	#ff55ff 	bright magenta
0xE 	0x3E 	63,63,21 	255,255,85 	#ffff55 	yellow
*/

void video_set_pixel( void *obj, const int x, const int y, const video_rgb_color_t color )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_draw_rectangle( void *obj, const int x, const int y, const int w, const int h, const video_rgb_color_t color )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_clear_screen( void *obj, const video_rgb_color_t color )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_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 )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_wait_for_retrace( void *obj )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_use_z_buffer( void *obj, bool use )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}

void video_refresh( void *obj )
{
	kernel_panic( "Calling abstract method in file %s at line %d.", __FILE__, __LINE__ ); 
}