15 void handle_key(int key);
16 void interrupt timer_intr();
17 int parse_args(int argc, char **argv);
20 static int opt_vsync = 1;
22 static unsigned long nframes;
24 volatile unsigned long nticks;
25 static void interrupt (*prev_timer_intr)();
27 static const char *mesh_fname;
28 static struct mesh mesh;
30 #define VERT(x, y, z) { x << 16, y << 16, z << 16, 0x10000 }
31 static struct g3d_vertex cube_varr[] = {
32 VERT(-1, -1, 1), VERT(1, -1, 1), VERT(1, -1, -1), VERT(-1, -1, -1),
33 VERT(-1, 1, 1), VERT(1, 1, 1), VERT(1, 1, -1), VERT(-1, 1, -1)
35 static struct meshface cube_faces[] = {
44 int main(int argc, char **argv)
48 unsigned long rate, total_ticks, sec;
50 if(parse_args(argc, argv) == -1) {
55 if(load_mesh(&mesh, mesh_fname) == -1) {
58 flip_mesh_winding(&mesh);
60 mesh.varr = cube_varr;
61 mesh.nverts = sizeof cube_varr / sizeof *cube_varr;
62 mesh.faces = cube_faces;
63 mesh.nfaces = sizeof cube_faces / sizeof *cube_faces;
65 for(i=0; i<mesh.nfaces; i++) {
66 mesh.faces[i].color = (i & 7) + 9;
71 for(i=0; i<256; i++) {
72 int r = XCOS(i << 1) >> 5;
73 int b = (255 - r) >> 1;
74 vid_setpalent(i, r, 8, b);
76 vid_setpalent(0, 0, 0, 0);
79 g3d_framebuffer(320, 200, 0);
81 mat_perspective(proj, 50, (4 << 16) / 3, 0x8000, 0x100000);
84 prev_timer_intr = _dos_getvect(0x1c);
85 _dos_setvect(0x1c, timer_intr);
100 total_ticks = nticks;
101 _dos_setvect(0x1c, prev_timer_intr);
106 /* 1.193182MHz / 65536 = 18.20651245117 ticks/sec */
107 rate = nframes * 1820 / nticks;
108 sec = nticks * 100 / 182;
109 printf("%lu frames in %lu.%lu sec - %lu.%lu fps\n", nframes,
110 sec / 10, sec % 10, rate / 100, rate % 100);
120 mat_trans(xform, 0, 0, -0x70000);
121 mat_mul_rotx(xform, nframes);
122 mat_mul_roty(xform, nframes);
123 g3d_modelview(xform);
125 g3d_fbpixels = vid_backbuf;
130 #ifdef USE_DIRTY_CLEAR
136 sort_mesh(&mesh, xform);
137 draw_mesh_zorder(&mesh);
142 void handle_key(int key)
155 void interrupt timer_intr()
158 _chain_intr(prev_timer_intr);
161 static const char *helpfmt = "Usage: %s [options] [mesh file]\n"
163 " -vsync: enable vsync (default)\n"
164 " -novsync: disable vsync\n"
165 " -help,-h: print usage and exit\n";
167 int parse_args(int argc, char **argv)
171 for(i=1; i<argc; i++) {
172 if(argv[i][0] == '-') {
173 if(strcmp(argv[i], "-vsync") == 0) {
175 } else if(strcmp(argv[i], "-novsync") == 0) {
177 } else if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) {
178 printf(helpfmt, argv[0]);
181 fprintf(stderr, "invalid option: %s\n", argv[i]);
186 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
189 mesh_fname = argv[i];
196 #define GC_ADDR 0x3ce
197 #define GC_DATA 0x3cf
202 unsigned char *img, *src, *dest;
203 unsigned char cmap[256][3];
209 for(i=0; i<256; i++) {
210 cmap[i][0] = inp(0x3c9) << 2;
211 cmap[i][1] = inp(0x3c9) << 2;
212 cmap[i][2] = inp(0x3c9) << 2;
216 if(!(img = malloc(320 * 400 * 3))) {
219 if(!(fp = fopen("vmem.ppm", "wb"))) {
224 src = (unsigned char*)0xa0000;
226 outp(0x3ce, 4); /* graphics controller: read map select register */
229 for(j=0; j<16000; j++) {
231 dest[0] = cmap[idx][0];
232 dest[1] = cmap[idx][1];
233 dest[2] = cmap[idx][2];
238 src = (unsigned char*)0xa4000;
240 outp(0x3ce, 4); /* graphics controller: read map select register */
243 for(j=0; j<16000; j++) {
245 dest[0] = cmap[idx][0];
246 dest[1] = cmap[idx][1];
247 dest[2] = cmap[idx][2];
252 fprintf(fp, "P6\n%d %d\n255\n", 320, 400);
253 fwrite(img, 1, 320 * 400 * 3, fp);