nuclear@1: #include nuclear@1: #include nuclear@1: #include nuclear@1: #include nuclear@1: #include "inttypes.h" nuclear@1: #include "gfx.h" nuclear@1: #include "keyb.h" nuclear@1: #include "mouse.h" nuclear@1: #include "logger.h" nuclear@6: #include "min3d.h" nuclear@6: #include "scene.h" nuclear@1: nuclear@6: static bool init(); nuclear@6: static void cleanup(); nuclear@1: static void display(); nuclear@1: static void swap_buffers(); nuclear@1: static void handle_keyboard(); nuclear@1: static void handle_mouse(); nuclear@1: static bool parse_args(int argc, char **argv); nuclear@1: nuclear@6: static int xsz = 640; nuclear@6: static int ysz = 480; nuclear@1: static int bpp = 16; nuclear@1: static int bytespp; nuclear@6: static bool novideo; nuclear@1: static unsigned char *fb; nuclear@1: static unsigned char *backbuf; nuclear@1: static int rbits, gbits, bbits; nuclear@1: static int rshift, gshift, bshift; nuclear@1: static unsigned int rmask, gmask, bmask; nuclear@1: nuclear@1: static bool quit; nuclear@1: nuclear@6: struct m3d_image rbuf; nuclear@6: static Scene *scn; nuclear@6: nuclear@1: int main(int argc, char **argv) nuclear@1: { nuclear@1: if(!parse_args(argc, argv)) { nuclear@1: return 1; nuclear@1: } nuclear@6: if(!init()) { nuclear@1: return 1; nuclear@1: } nuclear@1: nuclear@1: // main loop nuclear@1: for(;;) { nuclear@1: handle_keyboard(); nuclear@1: handle_mouse(); nuclear@1: if(quit) break; nuclear@1: nuclear@1: display(); nuclear@6: nuclear@6: if(novideo) break; nuclear@1: } nuclear@1: nuclear@6: cleanup(); nuclear@1: printf("Thank you for using Rayzor!\n"); nuclear@1: return 0; nuclear@1: } nuclear@1: nuclear@6: static bool init() nuclear@6: { nuclear@6: if(!novideo) { nuclear@6: if(kb_init(32) == -1) { nuclear@6: fprintf(stderr, "failed to initialize keyboard driver\n"); nuclear@6: return false; nuclear@6: } nuclear@6: nuclear@6: if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) { nuclear@6: set_text_mode(); nuclear@6: fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp); nuclear@6: return false; nuclear@6: } nuclear@6: bpp = get_color_depth(); nuclear@6: get_color_bits(&rbits, &gbits, &bbits); nuclear@6: get_color_shift(&rshift, &gshift, &bshift); nuclear@6: get_color_mask(&rmask, &gmask, &bmask); nuclear@6: bytespp = (int)ceil(bpp / 8.0); nuclear@6: nuclear@6: printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits); nuclear@6: printlog("shift: %d %d %d\n", rshift, gshift, bshift); nuclear@6: printlog("mask: %x %x %x\n", rmask, gmask, bmask); nuclear@6: } else { nuclear@6: logger_output(stdout); nuclear@6: printlog("novideo (debug) mode\n"); nuclear@6: bpp = 24; nuclear@6: rbits = gbits = bbits = 8; nuclear@6: bytespp = 3; nuclear@6: } nuclear@6: nuclear@6: backbuf = new unsigned char[xsz * ysz * 3]; nuclear@6: if(!backbuf) { nuclear@6: return false; nuclear@6: } nuclear@6: nuclear@6: m3d_init(); nuclear@6: rbuf.pixels = backbuf; nuclear@6: rbuf.xsz = xsz; nuclear@6: rbuf.ysz = ysz; nuclear@6: m3d_set_buffers(&rbuf, 0); nuclear@6: nuclear@6: m3d_matrix_mode(M3D_PROJECTION); nuclear@6: m3d_load_identity(); nuclear@6: m3d_perspective(50.0, (float)xsz / (float)ysz, 0.5, 500.0); nuclear@6: nuclear@6: scn = new Scene; nuclear@6: nuclear@6: Sphere *sph = new Sphere; nuclear@6: scn->add_object(sph); nuclear@6: nuclear@6: return true; nuclear@6: } nuclear@6: nuclear@6: static void cleanup() nuclear@6: { nuclear@6: delete scn; nuclear@6: nuclear@6: m3d_shutdown(); nuclear@6: delete [] backbuf; nuclear@6: nuclear@6: if(!novideo) { nuclear@6: set_text_mode(); nuclear@6: kb_shutdown(); nuclear@6: } nuclear@6: } nuclear@6: nuclear@6: nuclear@1: static void display() nuclear@1: { nuclear@6: m3d_clear(M3D_COLOR_BUFFER_BIT); nuclear@1: nuclear@6: m3d_matrix_mode(M3D_MODELVIEW); nuclear@6: m3d_load_identity(); nuclear@6: m3d_translate(0, 0, -10); nuclear@6: nuclear@6: scn->draw(); nuclear@6: nuclear@6: if(!novideo) { nuclear@6: swap_buffers(); nuclear@6: wait_vsync(); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: #define PACK_RGB(r, g, b) \ nuclear@1: ((((r) << rshift) & rmask) | \ nuclear@1: (((g) << gshift) & gmask) | \ nuclear@1: (((b) << bshift) & bmask)) nuclear@1: nuclear@1: static void swap_buffers() nuclear@1: { nuclear@1: unsigned char *src = backbuf; nuclear@1: int num_pixels = xsz * ysz; nuclear@1: nuclear@1: switch(bpp) { nuclear@1: case 32: nuclear@1: { nuclear@1: uint32_t *dest = (uint32_t*)fb; nuclear@1: for(int i=0; i> srs, src[1] >> sgs, src[2] >> sbs); nuclear@1: src += 3; nuclear@1: } nuclear@1: } nuclear@1: break; nuclear@1: nuclear@1: default: nuclear@1: break; nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: static void handle_keyboard() nuclear@1: { nuclear@5: int key; nuclear@1: nuclear@6: if(novideo) return; nuclear@6: nuclear@5: while((key = kb_getkey()) != -1) { nuclear@5: switch(key) { nuclear@5: case 27: nuclear@5: quit = true; nuclear@5: return; nuclear@5: } nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: static void handle_mouse() nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: static struct { nuclear@1: int opt; nuclear@1: const char *lopt; nuclear@1: const char *desc; nuclear@1: } options[] = { nuclear@1: {'s', "size", "resolution x[:bpp]"}, nuclear@6: {'n', "novid", "don't switch video mode (for debugging)"}, nuclear@1: {'h', "help", "print usage information and exit"}, nuclear@1: {-1, 0, 0} nuclear@1: }; nuclear@1: nuclear@1: static void print_usage(const char *argv0) nuclear@1: { nuclear@1: printf("%s usage\n", argv0); nuclear@1: for(int i=0; options[i].opt != -1; i++) { nuclear@1: printf(" -%c, -%s: %s\n", options[i].opt, options[i].lopt, options[i].desc); nuclear@1: } nuclear@1: exit(0); nuclear@1: } nuclear@1: nuclear@1: static bool parse_args(int argc, char **argv) nuclear@1: { nuclear@1: for(int i=1; i