rayzor

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