fallback to banked modes if LFB is not available
[eradicate] / src / dos / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "game.h"
5 #include "keyb.h"
6 #include "timer.h"
7 #include "gfx.h"
8 #include "logger.h"
9 #include "cdpmi.h"
10
11 static void draw(void);
12
13 static struct video_mode *vmode;
14
15 static void swap_lfb(void *pixels);
16 static void swap_banked(void *pixels);
17
18
19 int main(int argc, char **argv)
20 {
21         void *fb_buf;
22         struct video_mode *vmodes;
23         int vmidx, status = 0;
24
25         init_logger("game.log");
26
27         init_timer(100);
28         kb_init(32);
29
30         if(init_video() == -1) {
31                 return 1;
32         }
33         vmodes = video_modes();
34
35         if((vmidx = match_video_mode(640, 480, 16)) == -1) {
36                 return 1;
37         }
38         if(!(vmem = set_video_mode(vmidx, 1))) {
39                 return 1;
40         }
41         vmode = vmodes + vmidx;
42
43         if(vmode->fb_addr) {
44                 swap_buffers = swap_lfb;
45         } else {
46                 swap_buffers = swap_banked;
47         }
48
49         fb_width = vmode->xsz;
50         fb_height = vmode->ysz;
51         fb_size = vmode->pitch * vmode->ysz;
52
53         if(!(fb_buf = malloc(fb_size + vmode->pitch * 2))) {
54                 fprintf(stderr, "failed to allocate framebuffer\n");
55                 status = -1;
56                 goto break_evloop;
57         }
58         fb_pixels = (char*)fb_buf + vmode->pitch;
59
60         reset_timer();
61
62         for(;;) {
63                 int key;
64                 while((key = kb_getkey()) != -1) {
65                         if(key == 27) goto break_evloop;
66                 }
67
68                 time_msec = get_msec();
69                 draw();
70         }
71
72 break_evloop:
73         free(fb_buf);
74         set_text_mode();
75         cleanup_video();
76         kb_shutdown();
77         return status;
78 }
79
80 static void draw(void)
81 {
82         int i, j;
83         uint16_t *pptr = fb_pixels;
84
85         for(i=0; i<fb_height; i++) {
86                 for(j=0; j<fb_width; j++) {
87                         int chess = ((i >> 4) & 1) == ((j >> 4) & 1);
88                         *pptr++ = chess ? 0xff00 : 0x00ff;
89                 }
90         }
91
92         swap_buffers(fb_pixels);
93 }
94
95 static void swap_lfb(void *pixels)
96 {
97         wait_vsync();
98         memcpy(vmem, pixels, fb_size);
99 }
100
101 static void swap_banked(void *pixels)
102 {
103         int i, sz;
104         unsigned int pending;
105         unsigned char *pptr = pixels;
106         uint32_t offs = 0;
107
108         wait_vsync();
109
110         /* assume window is always at 0 at the beginning */
111         pending = fb_size;
112         while(pending > 0) {
113                 sz = pending > vmode->bank_size ? vmode->bank_size : pending;
114                 memcpy(vmem, pptr, sz);
115                 pptr += sz;
116                 pending -= sz;
117                 vbe_setwin(0, ++offs);
118         }
119
120         vbe_setwin(0, 0);
121 }