rayzor

view src/main.cc @ 6:a68dbf80d547

finally showing something ... :)
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 07 Apr 2014 06:04:11 +0300
parents 5fcf72837b69
children 75bc89c2abc4
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include "inttypes.h"
6 #include "gfx.h"
7 #include "keyb.h"
8 #include "mouse.h"
9 #include "logger.h"
10 #include "min3d.h"
11 #include "scene.h"
13 static bool init();
14 static void cleanup();
15 static void display();
16 static void swap_buffers();
17 static void handle_keyboard();
18 static void handle_mouse();
19 static bool parse_args(int argc, char **argv);
21 static int xsz = 640;
22 static int ysz = 480;
23 static int bpp = 16;
24 static int bytespp;
25 static bool novideo;
26 static unsigned char *fb;
27 static unsigned char *backbuf;
28 static int rbits, gbits, bbits;
29 static int rshift, gshift, bshift;
30 static unsigned int rmask, gmask, bmask;
32 static bool quit;
34 struct m3d_image rbuf;
35 static Scene *scn;
37 int main(int argc, char **argv)
38 {
39 if(!parse_args(argc, argv)) {
40 return 1;
41 }
42 if(!init()) {
43 return 1;
44 }
46 // main loop
47 for(;;) {
48 handle_keyboard();
49 handle_mouse();
50 if(quit) break;
52 display();
54 if(novideo) break;
55 }
57 cleanup();
58 printf("Thank you for using Rayzor!\n");
59 return 0;
60 }
62 static bool init()
63 {
64 if(!novideo) {
65 if(kb_init(32) == -1) {
66 fprintf(stderr, "failed to initialize keyboard driver\n");
67 return false;
68 }
70 if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) {
71 set_text_mode();
72 fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp);
73 return false;
74 }
75 bpp = get_color_depth();
76 get_color_bits(&rbits, &gbits, &bbits);
77 get_color_shift(&rshift, &gshift, &bshift);
78 get_color_mask(&rmask, &gmask, &bmask);
79 bytespp = (int)ceil(bpp / 8.0);
81 printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
82 printlog("shift: %d %d %d\n", rshift, gshift, bshift);
83 printlog("mask: %x %x %x\n", rmask, gmask, bmask);
84 } else {
85 logger_output(stdout);
86 printlog("novideo (debug) mode\n");
87 bpp = 24;
88 rbits = gbits = bbits = 8;
89 bytespp = 3;
90 }
92 backbuf = new unsigned char[xsz * ysz * 3];
93 if(!backbuf) {
94 return false;
95 }
97 m3d_init();
98 rbuf.pixels = backbuf;
99 rbuf.xsz = xsz;
100 rbuf.ysz = ysz;
101 m3d_set_buffers(&rbuf, 0);
103 m3d_matrix_mode(M3D_PROJECTION);
104 m3d_load_identity();
105 m3d_perspective(50.0, (float)xsz / (float)ysz, 0.5, 500.0);
107 scn = new Scene;
109 Sphere *sph = new Sphere;
110 scn->add_object(sph);
112 return true;
113 }
115 static void cleanup()
116 {
117 delete scn;
119 m3d_shutdown();
120 delete [] backbuf;
122 if(!novideo) {
123 set_text_mode();
124 kb_shutdown();
125 }
126 }
129 static void display()
130 {
131 m3d_clear(M3D_COLOR_BUFFER_BIT);
133 m3d_matrix_mode(M3D_MODELVIEW);
134 m3d_load_identity();
135 m3d_translate(0, 0, -10);
137 scn->draw();
139 if(!novideo) {
140 swap_buffers();
141 wait_vsync();
142 }
143 }
145 #define PACK_RGB(r, g, b) \
146 ((((r) << rshift) & rmask) | \
147 (((g) << gshift) & gmask) | \
148 (((b) << bshift) & bmask))
150 static void swap_buffers()
151 {
152 unsigned char *src = backbuf;
153 int num_pixels = xsz * ysz;
155 switch(bpp) {
156 case 32:
157 {
158 uint32_t *dest = (uint32_t*)fb;
159 for(int i=0; i<num_pixels; i++) {
160 *dest++ = PACK_RGB(src[0], src[1], src[2]);
161 src += 3;
162 }
163 }
164 break;
166 case 24:
167 memcpy(fb, backbuf, num_pixels * 3);
168 break;
170 case 16:
171 case 15:
172 {
173 int srs = 8 - rbits;
174 int sgs = 8 - gbits;
175 int sbs = 8 - bbits;
176 uint16_t *dest = (uint16_t*)fb;
177 for(int i=0; i<num_pixels; i++) {
178 *dest++ = PACK_RGB(src[0] >> srs, src[1] >> sgs, src[2] >> sbs);
179 src += 3;
180 }
181 }
182 break;
184 default:
185 break;
186 }
187 }
189 static void handle_keyboard()
190 {
191 int key;
193 if(novideo) return;
195 while((key = kb_getkey()) != -1) {
196 switch(key) {
197 case 27:
198 quit = true;
199 return;
200 }
201 }
202 }
204 static void handle_mouse()
205 {
206 }
208 static struct {
209 int opt;
210 const char *lopt;
211 const char *desc;
212 } options[] = {
213 {'s', "size", "resolution <xres>x<yres>[:bpp]"},
214 {'n', "novid", "don't switch video mode (for debugging)"},
215 {'h', "help", "print usage information and exit"},
216 {-1, 0, 0}
217 };
219 static void print_usage(const char *argv0)
220 {
221 printf("%s usage\n", argv0);
222 for(int i=0; options[i].opt != -1; i++) {
223 printf(" -%c, -%s: %s\n", options[i].opt, options[i].lopt, options[i].desc);
224 }
225 exit(0);
226 }
228 static bool parse_args(int argc, char **argv)
229 {
230 for(int i=1; i<argc; i++) {
231 if(argv[i][0] == '-') {
232 int opt = -1;
234 for(int j=0; options[j].opt != -1; j++) {
235 if(argv[i][2] == 0) {
236 if(argv[i][1] == options[j].opt) {
237 opt = options[j].opt;
238 break;
239 }
240 } else {
241 if(strcmp(argv[i] + 1, options[j].lopt) == 0) {
242 opt = options[j].opt;
243 break;
244 }
245 }
246 }
248 switch(opt) {
249 case 's':
250 if(sscanf(argv[++i], "%dx%d:%d", &xsz, &ysz, &bpp) < 2) {
251 fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]);
252 return false;
253 }
254 break;
256 case 'n':
257 novideo = true;
258 break;
260 case 'h':
261 print_usage(argv[0]); // doesn't return
262 break;
264 default:
265 fprintf(stderr, "unknown option: %s\n", argv[i]);
266 return false;
267 }
268 } else {
269 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
270 return false;
271 }
272 }
273 return true;
274 }