rayzor

diff src/main.cc @ 9:70e332156d02

moving along
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 10 Apr 2014 02:31:31 +0300
parents 75bc89c2abc4
children 235c8b764c0b
line diff
     1.1 --- a/src/main.cc	Mon Apr 07 08:46:06 2014 +0300
     1.2 +++ b/src/main.cc	Thu Apr 10 02:31:31 2014 +0300
     1.3 @@ -8,41 +8,40 @@
     1.4  #include "keyb.h"
     1.5  #include "mouse.h"
     1.6  #include "logger.h"
     1.7 -#include "min3d.h"
     1.8  #include "scene.h"
     1.9 +#include "rayzor.h"
    1.10 +#include "screen.h"
    1.11 +#include "modeller.h"
    1.12 +#include "renderer.h"
    1.13 +#include "scrman.h"
    1.14  
    1.15  static bool init();
    1.16  static void cleanup();
    1.17  static void display();
    1.18  static void swap_buffers();
    1.19 -static void draw_cursor(unsigned char *buf, int mx, int my);
    1.20 +static void draw_cursor(uint32_t *buf, int mx, int my);
    1.21  static void handle_keyboard();
    1.22  static void handle_mouse();
    1.23 -static void mouse_button(int bn, int x, int y);
    1.24 -static void mouse_motion(int x, int y);
    1.25  static bool parse_args(int argc, char **argv);
    1.26  static void sig(int s);
    1.27  
    1.28 -static int xsz = 640;
    1.29 -static int ysz = 480;
    1.30 -static int bpp = 24;
    1.31 +uint32_t *fb_pixels;
    1.32 +int fb_width = 640;
    1.33 +int fb_height = 480;
    1.34 +int fb_bpp = 32;
    1.35 +Scene *scene;
    1.36 +
    1.37  static int bytespp;
    1.38  static bool novideo;
    1.39 -static unsigned char *fb;
    1.40 -static unsigned char *backbuf;
    1.41 +static void *fb;
    1.42  static int rbits, gbits, bbits;
    1.43  static int rshift, gshift, bshift;
    1.44  static unsigned int rmask, gmask, bmask;
    1.45  
    1.46 -static int mx, my;	// mouse cursor
    1.47 -static float cam_theta, cam_phi = 25, cam_dist = 8;
    1.48 -
    1.49  static bool use_mouse;
    1.50 +static int mouse_x, mouse_y;
    1.51  static bool quit;
    1.52  
    1.53 -struct m3d_image rbuf;
    1.54 -static Scene *scn;
    1.55 -
    1.56  int main(int argc, char **argv)
    1.57  {
    1.58  	if(!parse_args(argc, argv)) {
    1.59 @@ -68,6 +67,11 @@
    1.60  	return 0;
    1.61  }
    1.62  
    1.63 +void quit_app()
    1.64 +{
    1.65 +	quit = true;
    1.66 +}
    1.67 +
    1.68  static bool init()
    1.69  {
    1.70  	signal(SIGINT, sig);
    1.71 @@ -81,62 +85,65 @@
    1.72  			return false;
    1.73  		}
    1.74  
    1.75 -		if(!(fb = (unsigned char*)set_video_mode(xsz, ysz, bpp))) {
    1.76 +		if(!(fb = set_video_mode(fb_width, fb_height, fb_bpp))) {
    1.77  			set_text_mode();
    1.78 -			fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", xsz, ysz, bpp);
    1.79 +			fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", fb_width, fb_height, fb_bpp);
    1.80  			return false;
    1.81  		}
    1.82 -		bpp = get_color_depth();
    1.83 +		fb_bpp = get_color_depth();
    1.84  		get_color_bits(&rbits, &gbits, &bbits);
    1.85  		get_color_shift(&rshift, &gshift, &bshift);
    1.86  		get_color_mask(&rmask, &gmask, &bmask);
    1.87 -		bytespp = (int)ceil(bpp / 8.0);
    1.88 +		bytespp = (int)ceil(fb_bpp / 8.0);
    1.89  
    1.90 -		printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
    1.91 +		printlog("bpp: %d (%d %d %d)\n", fb_bpp, rbits, gbits, bbits);
    1.92  		printlog("shift: %d %d %d\n", rshift, gshift, bshift);
    1.93  		printlog("mask: %x %x %x\n", rmask, gmask, bmask);
    1.94  
    1.95  		if(have_mouse()) {
    1.96  			use_mouse = true;
    1.97 -			set_mouse_limits(0, 0, xsz - 1, ysz - 1);
    1.98 +			set_mouse_limits(0, 0, fb_width - 1, fb_height - 1);
    1.99  		}
   1.100  	} else {
   1.101  		logger_output(stdout);
   1.102  		printlog("novideo (debug) mode\n");
   1.103 -		bpp = 24;
   1.104 +		fb_bpp = 32;
   1.105  		rbits = gbits = bbits = 8;
   1.106  		bytespp = 3;
   1.107  	}
   1.108  
   1.109 -	backbuf = new unsigned char[xsz * ysz * 3];
   1.110 -	if(!backbuf) {
   1.111 +	fb_pixels = new uint32_t[fb_width * fb_height * 4];
   1.112 +	if(!fb_pixels) {
   1.113  		return false;
   1.114  	}
   1.115  
   1.116 -	m3d_init();
   1.117 -	rbuf.pixels = backbuf;
   1.118 -	rbuf.xsz = xsz;
   1.119 -	rbuf.ysz = ysz;
   1.120 -	m3d_set_buffers(&rbuf, 0);
   1.121 -
   1.122 -	m3d_matrix_mode(M3D_PROJECTION);
   1.123 -	m3d_load_identity();
   1.124 -	m3d_perspective(50.0, (float)xsz / (float)ysz, 0.5, 500.0);
   1.125 -
   1.126 -	scn = new Scene;
   1.127 +	scene = new Scene;
   1.128  
   1.129  	Sphere *sph = new Sphere;
   1.130 -	scn->add_object(sph);
   1.131 +	scene->add_object(sph);
   1.132  
   1.133 +	Modeller *modeller = new Modeller;
   1.134 +	if(!modeller->init()) {
   1.135 +		return false;
   1.136 +	}
   1.137 +	add_screen(modeller);
   1.138 +
   1.139 +	Renderer *renderer = new Renderer;
   1.140 +	if(!renderer->init()) {
   1.141 +		return false;
   1.142 +	}
   1.143 +	add_screen(renderer);
   1.144 +
   1.145 +	activate_screen(modeller); // start the modeller screen
   1.146  	return true;
   1.147  }
   1.148  
   1.149  static void cleanup()
   1.150  {
   1.151 -	delete scn;
   1.152 +	delete scene;
   1.153 +	delete [] fb_pixels;
   1.154  
   1.155 -	m3d_shutdown();
   1.156 -	delete [] backbuf;
   1.157 +	destroy_screens();
   1.158  
   1.159  	if(!novideo) {
   1.160  		set_text_mode();
   1.161 @@ -144,22 +151,17 @@
   1.162  	}
   1.163  }
   1.164  
   1.165 -
   1.166  static void display()
   1.167  {
   1.168 -	m3d_clear(M3D_COLOR_BUFFER_BIT);
   1.169 -
   1.170 -	m3d_matrix_mode(M3D_MODELVIEW);
   1.171 -	m3d_load_identity();
   1.172 -	m3d_translate(0, 0, -cam_dist);
   1.173 -	m3d_rotate(cam_phi, 1, 0, 0);
   1.174 -	m3d_rotate(cam_theta, 0, 1, 0);
   1.175 -
   1.176 -	scn->draw();
   1.177 +	Screen *scr = active_screen();
   1.178 +	if(scr) {
   1.179 +		scr->update();
   1.180 +		scr->draw();
   1.181 +	}
   1.182  
   1.183  	// draw the mouse cursor
   1.184  	if(use_mouse) {
   1.185 -		draw_cursor(backbuf, mx, my);
   1.186 +		draw_cursor(fb_pixels, mouse_x, mouse_y);
   1.187  	}
   1.188  
   1.189  	if(!novideo) {
   1.190 @@ -173,36 +175,43 @@
   1.191  	 (((g) << gshift) & gmask) | \
   1.192  	 (((b) << bshift) & bmask))
   1.193  
   1.194 +#define UNPACK_RED(c)	(((c) >> 16) & 0xff)
   1.195 +#define UNPACK_GREEN(c)	(((c) >> 8) & 0xff)
   1.196 +#define UNPACK_BLUE(c)	((c) & 0xff)
   1.197 +
   1.198  static void swap_buffers()
   1.199  {
   1.200 -	unsigned char *src = backbuf;
   1.201 -	int num_pixels = xsz * ysz;
   1.202 +	uint32_t *src = fb_pixels;
   1.203 +	int num_pixels = fb_width * fb_height;
   1.204  
   1.205 -	switch(bpp) {
   1.206 +	switch(fb_bpp) {
   1.207  	case 32:
   1.208 -		{
   1.209 -			uint32_t *dest = (uint32_t*)fb;
   1.210 -			for(int i=0; i<num_pixels; i++) {
   1.211 -				*dest++ = PACK_RGB(src[0], src[1], src[2]);
   1.212 -				src += 3;
   1.213 -			}
   1.214 -		}
   1.215 +		memcpy(fb, fb_pixels, num_pixels * 4);
   1.216  		break;
   1.217  
   1.218  	case 24:
   1.219 -		memcpy(fb, backbuf, num_pixels * 3);
   1.220 +		{
   1.221 +			unsigned char *dest = (unsigned char*)fb;
   1.222 +			for(int i=0; i<num_pixels; i++) {
   1.223 +				uint32_t c = *src++;
   1.224 +				*dest++ = UNPACK_RED(c);
   1.225 +				*dest++ = UNPACK_GREEN(c);
   1.226 +				*dest++ = UNPACK_BLUE(c);
   1.227 +			}
   1.228 +		}
   1.229  		break;
   1.230  
   1.231  	case 16:
   1.232  	case 15:
   1.233  		{
   1.234 -			int srs = 8 - rbits;
   1.235 -			int sgs = 8 - gbits;
   1.236 -			int sbs = 8 - bbits;
   1.237  			uint16_t *dest = (uint16_t*)fb;
   1.238  			for(int i=0; i<num_pixels; i++) {
   1.239 -				*dest++ = PACK_RGB(src[0] >> srs, src[1] >> sgs, src[2] >> sbs);
   1.240 -				src += 3;
   1.241 +				uint32_t c = *src++;
   1.242 +				unsigned char r = UNPACK_RED(c);
   1.243 +				unsigned char g = UNPACK_GREEN(c);
   1.244 +				unsigned char b = UNPACK_BLUE(c);
   1.245 +
   1.246 +				*dest++ = PACK_RGB(r, g, b);
   1.247  			}
   1.248  		}
   1.249  		break;
   1.250 @@ -212,104 +221,72 @@
   1.251  	}
   1.252  }
   1.253  
   1.254 -static void draw_cursor(unsigned char *buf, int mx, int my)
   1.255 +static void draw_cursor(uint32_t *buf, int mx, int my)
   1.256  {
   1.257 -	unsigned char *cptr = buf + (my * xsz + mx) * 3;
   1.258 +	uint32_t *cptr = buf + my * fb_width + mx;
   1.259  	int i, cw[2] = {4, 4}, ch[2] = {4, 4};
   1.260  
   1.261  	if(mx < cw[0]) cw[0] = mx;
   1.262  	if(my < ch[0]) ch[0] = my;
   1.263 -	if(xsz - mx < cw[1]) cw[1] = xsz - mx - 1;
   1.264 -	if(ysz - my < ch[1]) ch[1] = ysz - my - 1;
   1.265 +	if(fb_width - mx < cw[1]) cw[1] = fb_width - mx - 1;
   1.266 +	if(fb_height - my < ch[1]) ch[1] = fb_height - my - 1;
   1.267  
   1.268  	for(i=1; i<cw[0]; i++) {
   1.269 -		int idx = -i * 3;
   1.270 -		cptr[idx] = 255;
   1.271 -		cptr[idx + 1] = 255;
   1.272 -		cptr[idx + 2] = 255;
   1.273 +		int idx = -i;
   1.274 +		cptr[idx] = 0xffffff;
   1.275  	}
   1.276  	for(i=1; i<cw[1]; i++) {
   1.277 -		int idx = i * 3;
   1.278 -		cptr[idx] = 255;
   1.279 -		cptr[idx + 1] = 255;
   1.280 -		cptr[idx + 2] = 255;
   1.281 +		int idx = i;
   1.282 +		cptr[idx] = 0xffffff;
   1.283  	}
   1.284  	for(i=1; i<ch[0]; i++) {
   1.285 -		int idx = -i * xsz * 3;
   1.286 -		cptr[idx] = 255;
   1.287 -		cptr[idx + 1] = 255;
   1.288 -		cptr[idx + 2] = 255;
   1.289 +		int idx = -i * fb_width;
   1.290 +		cptr[idx] = 0xffffff;
   1.291  	}
   1.292  	for(i=1; i<ch[1]; i++) {
   1.293 -		int idx = i * xsz * 3;
   1.294 -		cptr[idx] = 255;
   1.295 -		cptr[idx + 1] = 255;
   1.296 -		cptr[idx + 2] = 255;
   1.297 +		int idx = i * fb_width;
   1.298 +		cptr[idx] = 0xffffff;
   1.299  	}
   1.300  }
   1.301  
   1.302  static void handle_keyboard()
   1.303  {
   1.304  	int key;
   1.305 +	Screen *scr = active_screen();
   1.306  
   1.307  	if(novideo) return;
   1.308  
   1.309  	while((key = kb_getkey()) != -1) {
   1.310 -		switch(key) {
   1.311 -		case 27:
   1.312 -			quit = true;
   1.313 -			return;
   1.314 -		}
   1.315 +		scr->handle_keyboard(key, true);	// TODO also generate release events...
   1.316  	}
   1.317  }
   1.318  
   1.319  static void handle_mouse()
   1.320  {
   1.321 -	static int prev_mx, prev_my, prev_bnmask;
   1.322 -	int /*mx, my,*/ bnmask;
   1.323 +	static int prev_mx, prev_my, prev_bnmask, bndiff;
   1.324 +	int mx, my, bnmask;
   1.325 +	Screen *scr = active_screen();
   1.326  
   1.327  	if(!use_mouse || novideo) return;
   1.328  
   1.329  	bnmask = read_mouse(&mx, &my);
   1.330 -	if(bnmask != prev_bnmask) {
   1.331 -		mouse_button(bnmask, mx, my);
   1.332 -		prev_bnmask = bnmask;
   1.333 +	if(scr && (bndiff = bnmask ^ prev_bnmask)) {
   1.334 +		for(int i=0; i<8; i++) {
   1.335 +			int bit = 1 << i;
   1.336 +			if(bndiff & bit) {
   1.337 +				scr->handle_mbutton(i, bnmask & bit, mx, my);
   1.338 +			}
   1.339 +		}
   1.340  	}
   1.341 -	if(mx != prev_mx || my != prev_my) {
   1.342 -		mouse_motion(mx, my);
   1.343 -		prev_mx = mx;
   1.344 -		prev_my = my;
   1.345 +	prev_bnmask = bnmask;
   1.346 +
   1.347 +	if(scr && (mx != prev_mx || my != prev_my)) {
   1.348 +		scr->handle_mmotion(mx, my);
   1.349  	}
   1.350 +	prev_mx = mx;
   1.351 +	prev_my = my;
   1.352  }
   1.353  
   1.354 -static int bnstate;
   1.355 -static int prev_x = -1, prev_y;
   1.356 -static void mouse_button(int bn, int x, int y)
   1.357 -{
   1.358 -	bnstate = bn;
   1.359 -	prev_x = x;
   1.360 -	prev_y = y;
   1.361 -}
   1.362 -
   1.363 -static void mouse_motion(int x, int y)
   1.364 -{
   1.365 -	int dx = x - prev_x;
   1.366 -	int dy = y - prev_y;
   1.367 -	prev_x = x;
   1.368 -	prev_y = y;
   1.369 -
   1.370 -	if(bnstate & 1) {
   1.371 -		cam_theta += dx * 0.5;
   1.372 -		cam_phi += dy * 0.5;
   1.373 -
   1.374 -		if(cam_phi < -90) cam_phi = -90;
   1.375 -		if(cam_phi > 90) cam_phi = 90;
   1.376 -	}
   1.377 -	if(bnstate & 2) {
   1.378 -		cam_dist += dy * 0.1;
   1.379 -		if(cam_dist < 0) cam_dist = 0;
   1.380 -	}
   1.381 -}
   1.382  
   1.383  static struct {
   1.384  	int opt;
   1.385 @@ -353,7 +330,7 @@
   1.386  
   1.387  			switch(opt) {
   1.388  			case 's':
   1.389 -				if(sscanf(argv[++i], "%dx%d:%d", &xsz, &ysz, &bpp) < 2) {
   1.390 +				if(sscanf(argv[++i], "%dx%d:%d", &fb_width, &fb_height, &fb_bpp) < 2) {
   1.391  					fprintf(stderr, "%s must be followed by a resolution: WxH\n", argv[i - 1]);
   1.392  					return false;
   1.393  				}
   1.394 @@ -383,4 +360,5 @@
   1.395  {
   1.396  	cleanup();
   1.397  	fprintf(stderr, "signal caught: %d\n", s);
   1.398 +	exit(1);
   1.399  }