3d cube and dirty drawing
[dos_low3d] / src / main.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <conio.h>
7 #include <dos.h>
8 #include "video.h"
9 #include "3dgfx.h"
10 #include "vmath.h"
11 #include "util.h"
12
13 void update(void);
14 void handle_key(int key);
15 void interrupt timer_intr();
16
17 static int quit;
18 static unsigned char *fb;
19 static long nframes;
20
21 volatile unsigned long nticks;
22
23 static void interrupt (*prev_timer_intr)();
24
25 int main(void)
26 {
27         int32_t proj[16];
28         long rate;
29
30         if(!(fb = calloc(1, 64000))) {
31                 fprintf(stderr, "failed to allocate framebuffer\n");
32                 return 1;
33         }
34
35         init_video();
36
37         g3d_init();
38         g3d_framebuffer(320, 200, fb);
39
40         mat_perspective(proj, 50, (4 << 16) / 3, 0x8000, 0x100000);
41         g3d_projection(proj);
42
43         prev_timer_intr = _dos_getvect(0x1c);
44         _dos_setvect(0x1c, timer_intr);
45
46         for(;;) {
47                 while(kbhit()) {
48                         int c = getch();
49                         handle_key(c);
50                         if(quit) goto end;
51                 }
52
53                 update();
54                 nframes++;
55         }
56
57 end:
58         _dos_setvect(0x1c, prev_timer_intr);
59
60         close_video();
61         free(fb);
62
63         rate = nframes * 100 * 18 / nticks;
64         printf("%ld frames in %ld sec, rate: %ld.%ld\n", nframes, nticks / 18,
65                         rate / 100, rate % 100);
66         return 0;
67 }
68
69 #define VERT(x, y, z) { x << 16, y << 16, z << 16, 0x10000 }
70 struct g3d_vertex varr[] = {
71         VERT(-1, -1, 1), VERT(1, -1, 1), VERT(1, 1, 1), VERT(-1, 1, 1),
72         VERT(1, -1, 1), VERT(1, -1, -1), VERT(1, 1, -1), VERT(1, 1, 1),
73         VERT(1, -1, -1), VERT(-1, -1, -1), VERT(-1, 1, -1), VERT(1, 1, -1),
74         VERT(-1, -1, -1), VERT(-1, -1, 1), VERT(-1, 1, 1), VERT(-1, 1, -1),
75         VERT(-1, 1, 1), VERT(1, 1, 1), VERT(1, 1, -1), VERT(-1, 1, -1),
76         VERT(-1, -1, -1), VERT(1, -1, -1), VERT(1, -1, 1), VERT(-1, -1, 1)
77 };
78
79 void update(void)
80 {
81         int32_t xform[16];
82
83 #ifdef USE_DIRTY_CLEAR
84         g3d_clear_dirty();
85 #else
86         vid_clearfb(fb);
87 #endif
88
89         mat_trans(xform, 0, 0, -0x40000);
90         mat_mul_rotx(xform, nframes);
91         mat_mul_roty(xform, nframes);
92         g3d_modelview(xform);
93
94         g3d_color(9);
95         g3d_draw(G3D_QUADS, varr, 4);
96         g3d_color(10);
97         g3d_draw(G3D_QUADS, varr + 4, 4);
98         g3d_color(11);
99         g3d_draw(G3D_QUADS, varr + 8, 4);
100         g3d_color(12);
101         g3d_draw(G3D_QUADS, varr + 12, 4);
102         g3d_color(13);
103         g3d_draw(G3D_QUADS, varr + 16, 4);
104         g3d_color(14);
105         g3d_draw(G3D_QUADS, varr + 20, 4);
106
107 #ifdef USE_VSYNC
108         wait_vsync();
109 #endif
110 #ifdef USE_DIRTY_COPY
111         g3d_copy_dirty();
112 #else
113         vid_copyfb(fb);
114 #endif
115 }
116
117 void handle_key(int key)
118 {
119         switch(key) {
120         case 27:
121                 quit = 1;
122                 break;
123         }
124 }
125
126 void interrupt timer_intr()
127 {
128         nticks++;
129         _chain_intr(prev_timer_intr);
130 }