11 struct vid_driver *vid_drvlist[MAX_DRV];
17 static struct vid_modeinfo **modes, *cur_mode;
18 static int num_modes, max_modes;
24 struct vid_modeinfo *vm;
30 num_modes = max_modes = 0;
35 if(dpmi_init() == -1) {
43 for(i=0; i<vid_numdrv; i++) {
44 struct vid_driver *drv = vid_drvlist[i];
48 for(j=0; j<drv->num_modes; j++) {
49 if(num_modes >= max_modes) {
50 int newsz = max_modes ? max_modes * 2 : 128;
51 void *tmp = realloc(modes, newsz * sizeof *modes);
53 errormsg("failed to allocate modes list\n");
60 modes[num_modes++] = drv->modes + j;
64 infomsg("found %d modes:\n", num_modes);
65 for(i=0; i<num_modes; i+=2) {
67 len = infomsg("[%4s] %04x: %dx%d %dbpp", vm->drv->name, vm->modeno,
68 vm->width, vm->height, vm->bpp);
69 if(i + 1 >= num_modes) {
73 for(j=len; j<40; j++) infomsg(" ");
75 infomsg("[%4s] %04x: %dx%d %dbpp\n", vm->drv->name, vm->modeno,
76 vm->width, vm->height, vm->bpp);
82 void vid_cleanup(void)
86 if(cur_mode && cur_mode->modeno != 3) {
90 if(vid_vmem >= (void*)0x100000) {
91 dpmi_munmap(vid_vmem);
94 for(i=0; i<vid_numdrv; i++) {
95 struct vid_driver *drv = vid_drvlist[i];
104 int vid_curmode(void)
107 return cur_mode->modeno;
112 void *vid_setmode(int mode)
115 struct vid_driver *drv;
117 for(i=0; i<num_modes; i++) {
118 if(modes[i]->modeno == mode) {
120 if(drv->ops->setmode(mode) == 0) {
123 if(vid_vmem >= (void*)0x100000) {
124 assert(vid_vmem_size);
125 dpmi_munmap(vid_vmem);
128 if(modes[i]->vmem_addr < 0x100000) {
129 vid_vmem = (void*)modes[i]->vmem_addr;
132 vid_vmem = dpmi_mmap(modes[i]->vmem_addr, modes[i]->vmem_size);
133 vid_vmem_size = modes[i]->vmem_size;
142 #define EQUIV_BPP(a, b) \
143 ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \
144 ((a) == 24 && (b) == 32) || ((a) == 32 && (b) == 24))
146 int vid_findmode(int xsz, int ysz, int bpp)
150 for(i=0; i<num_modes; i++) {
151 if(modes[i]->width == xsz && modes[i]->height == ysz && modes[i]->bpp == bpp) {
152 return modes[i]->modeno;
156 /* try fuzzy bpp matching */
157 for(i=0; i<num_modes; i++) {
158 if(modes[i]->width == xsz && modes[i]->height == ysz &&
159 EQUIV_BPP(modes[i]->bpp, bpp)) {
160 return modes[i]->modeno;
168 struct vid_modeinfo *vid_modeinfo(int mode)
172 for(i=0; i<num_modes; i++) {
173 if(modes[i]->modeno == mode) {
180 int vid_islinear(void)
182 return !vid_isbanked();
185 int vid_isbanked(void)
187 return cur_mode->win_size && vid_vmem < (void*)0x100000;
190 void vid_setpal(int idx, int count, const struct vid_color *col)
192 cur_mode->ops.setpal(idx, count, col);
195 void vid_getpal(int idx, int count, struct vid_color *col)
197 cur_mode->ops.getpal(idx, count, col);
200 void vid_blit(int x, int y, int w, int h, void *src, int pitch)
203 pitch = cur_mode->width << 2;
205 cur_mode->ops.blit(x, y, w, h, src, pitch);
208 void vid_blitfb(void *fb, int pitch)
211 pitch = cur_mode->width << 2;
213 cur_mode->ops.blitfb(fb, pitch);
216 void vid_blit32(int x, int y, int w, int h, uint32_t *src, int pitch)
218 if(cur_mode->bpp == 32) {
219 vid_blit(x, y, w, h, src, pitch);
224 pitch = cur_mode->width << 2;
229 void vid_blitfb32(uint32_t *src, int pitch)
231 int i, j, winpos, winleft, endskip;
235 if(cur_mode->bpp == 32) {
236 vid_blitfb(src, pitch);
241 pitch = cur_mode->width << 2;
247 winleft = cur_mode->win_size << 10;
252 switch(cur_mode->bpp) {
266 endskip = cur_mode->pitch - cur_mode->width * 3;
268 for(i=0; i<cur_mode->height; i++) {
269 for(j=0; j<cur_mode->width; j++) {
270 uint32_t pixel = src[j];
272 winpos += cur_mode->win_step;
273 vid_setwin(0, winpos);
274 winleft = cur_mode->win_size << 10;
277 dest[0] = pixel & 0xff;
278 dest[1] = (pixel >> 8) & 0xff;
279 dest[2] = (pixel >> 16) & 0xff;
283 src = (uint32_t*)((char*)src + pitch);