rayzor

changeset 7:75bc89c2abc4

fixed the mouse handling problem
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 07 Apr 2014 08:05:06 +0300
parents a68dbf80d547
children fcd06a15dfdd
files src/main.cc src/mouse.c src/mouse.h
diffstat 3 files changed, 184 insertions(+), 42 deletions(-) [+]
line diff
     1.1 --- a/src/main.cc	Mon Apr 07 06:04:11 2014 +0300
     1.2 +++ b/src/main.cc	Mon Apr 07 08:05:06 2014 +0300
     1.3 @@ -2,6 +2,7 @@
     1.4  #include <stdlib.h>
     1.5  #include <string.h>
     1.6  #include <math.h>
     1.7 +#include <signal.h>
     1.8  #include "inttypes.h"
     1.9  #include "gfx.h"
    1.10  #include "keyb.h"
    1.11 @@ -14,13 +15,17 @@
    1.12  static void cleanup();
    1.13  static void display();
    1.14  static void swap_buffers();
    1.15 +static void draw_cursor(unsigned char *buf, int mx, int my);
    1.16  static void handle_keyboard();
    1.17  static void handle_mouse();
    1.18 +static void mouse_button(int bn, int x, int y);
    1.19 +static void mouse_motion(int x, int y);
    1.20  static bool parse_args(int argc, char **argv);
    1.21 +static void sig(int s);
    1.22  
    1.23  static int xsz = 640;
    1.24  static int ysz = 480;
    1.25 -static int bpp = 16;
    1.26 +static int bpp = 24;
    1.27  static int bytespp;
    1.28  static bool novideo;
    1.29  static unsigned char *fb;
    1.30 @@ -29,6 +34,10 @@
    1.31  static int rshift, gshift, bshift;
    1.32  static unsigned int rmask, gmask, bmask;
    1.33  
    1.34 +static int mx, my;	// mouse cursor
    1.35 +static float cam_theta, cam_phi = 25, cam_dist = 8;
    1.36 +
    1.37 +static bool use_mouse;
    1.38  static bool quit;
    1.39  
    1.40  struct m3d_image rbuf;
    1.41 @@ -61,6 +70,11 @@
    1.42  
    1.43  static bool init()
    1.44  {
    1.45 +	signal(SIGINT, sig);
    1.46 +	signal(SIGSEGV, sig);
    1.47 +	signal(SIGILL, sig);
    1.48 +	signal(SIGFPE, sig);
    1.49 +
    1.50  	if(!novideo) {
    1.51  		if(kb_init(32) == -1) {
    1.52  			fprintf(stderr, "failed to initialize keyboard driver\n");
    1.53 @@ -81,6 +95,11 @@
    1.54  		printlog("bpp: %d (%d %d %d)\n", bpp, rbits, gbits, bbits);
    1.55  		printlog("shift: %d %d %d\n", rshift, gshift, bshift);
    1.56  		printlog("mask: %x %x %x\n", rmask, gmask, bmask);
    1.57 +
    1.58 +		if(have_mouse()) {
    1.59 +			use_mouse = true;
    1.60 +			set_mouse_limits(0, 0, xsz - 1, ysz - 1);
    1.61 +		}
    1.62  	} else {
    1.63  		logger_output(stdout);
    1.64  		printlog("novideo (debug) mode\n");
    1.65 @@ -132,10 +151,17 @@
    1.66  
    1.67  	m3d_matrix_mode(M3D_MODELVIEW);
    1.68  	m3d_load_identity();
    1.69 -	m3d_translate(0, 0, -10);
    1.70 +	m3d_translate(0, 0, -cam_dist);
    1.71 +	m3d_rotate(cam_phi, 1, 0, 0);
    1.72 +	m3d_rotate(cam_theta, 0, 1, 0);
    1.73  
    1.74  	scn->draw();
    1.75  
    1.76 +	// draw the mouse cursor
    1.77 +	if(use_mouse) {
    1.78 +		draw_cursor(backbuf, mx, my);
    1.79 +	}
    1.80 +
    1.81  	if(!novideo) {
    1.82  		swap_buffers();
    1.83  		wait_vsync();
    1.84 @@ -186,6 +212,42 @@
    1.85  	}
    1.86  }
    1.87  
    1.88 +static void draw_cursor(unsigned char *buf, int mx, int my)
    1.89 +{
    1.90 +	unsigned char *cptr = buf + (my * xsz + mx) * 3;
    1.91 +	int i, cw[2] = {4, 4}, ch[2] = {4, 4};
    1.92 +
    1.93 +	if(mx < cw[0]) cw[0] = mx;
    1.94 +	if(my < ch[0]) ch[0] = my;
    1.95 +	if(xsz - mx < cw[1]) cw[1] = xsz - mx - 1;
    1.96 +	if(ysz - my < ch[1]) ch[1] = ysz - my - 1;
    1.97 +
    1.98 +	for(i=1; i<cw[0]; i++) {
    1.99 +		int idx = -i * 3;
   1.100 +		cptr[idx] = 255;
   1.101 +		cptr[idx + 1] = 255;
   1.102 +		cptr[idx + 2] = 255;
   1.103 +	}
   1.104 +	for(i=1; i<cw[1]; i++) {
   1.105 +		int idx = i * 3;
   1.106 +		cptr[idx] = 255;
   1.107 +		cptr[idx + 1] = 255;
   1.108 +		cptr[idx + 2] = 255;
   1.109 +	}
   1.110 +	for(i=1; i<ch[0]; i++) {
   1.111 +		int idx = -i * xsz * 3;
   1.112 +		cptr[idx] = 255;
   1.113 +		cptr[idx + 1] = 255;
   1.114 +		cptr[idx + 2] = 255;
   1.115 +	}
   1.116 +	for(i=1; i<ch[1]; i++) {
   1.117 +		int idx = i * xsz * 3;
   1.118 +		cptr[idx] = 255;
   1.119 +		cptr[idx + 1] = 255;
   1.120 +		cptr[idx + 2] = 255;
   1.121 +	}
   1.122 +}
   1.123 +
   1.124  static void handle_keyboard()
   1.125  {
   1.126  	int key;
   1.127 @@ -203,6 +265,50 @@
   1.128  
   1.129  static void handle_mouse()
   1.130  {
   1.131 +	static int prev_mx, prev_my, prev_bnmask;
   1.132 +	int /*mx, my,*/ bnmask;
   1.133 +
   1.134 +	if(!use_mouse || novideo) return;
   1.135 +
   1.136 +	bnmask = read_mouse(&mx, &my);
   1.137 +	if(bnmask != prev_bnmask) {
   1.138 +		mouse_button(bnmask, mx, my);
   1.139 +		prev_bnmask = bnmask;
   1.140 +	}
   1.141 +	if(mx != prev_mx || my != prev_my) {
   1.142 +		mouse_motion(mx, my);
   1.143 +		prev_mx = mx;
   1.144 +		prev_my = my;
   1.145 +	}
   1.146 +}
   1.147 +
   1.148 +static int bnstate;
   1.149 +static int prev_x = -1, prev_y;
   1.150 +static void mouse_button(int bn, int x, int y)
   1.151 +{
   1.152 +	bnstate = bn;
   1.153 +	prev_x = x;
   1.154 +	prev_y = y;
   1.155 +}
   1.156 +
   1.157 +static void mouse_motion(int x, int y)
   1.158 +{
   1.159 +	int dx = x - prev_x;
   1.160 +	int dy = y - prev_y;
   1.161 +	prev_x = x;
   1.162 +	prev_y = y;
   1.163 +
   1.164 +	if(bnstate & 1) {
   1.165 +		cam_theta += dx * 0.5;
   1.166 +		cam_phi += dy * 0.5;
   1.167 +
   1.168 +		if(cam_phi < -90) cam_phi = -90;
   1.169 +		if(cam_phi > 90) cam_phi = 90;
   1.170 +	}
   1.171 +	if(bnstate & 2) {
   1.172 +		cam_dist += dy * 0.1;
   1.173 +		if(cam_dist < 0) cam_dist = 0;
   1.174 +	}
   1.175  }
   1.176  
   1.177  static struct {
   1.178 @@ -272,3 +378,9 @@
   1.179  	}
   1.180  	return true;
   1.181  }
   1.182 +
   1.183 +static void sig(int s)
   1.184 +{
   1.185 +	cleanup();
   1.186 +	fprintf(stderr, "signal caught: %d\n", s);
   1.187 +}
     2.1 --- a/src/mouse.c	Mon Apr 07 06:04:11 2014 +0300
     2.2 +++ b/src/mouse.c	Mon Apr 07 08:05:06 2014 +0300
     2.3 @@ -1,7 +1,5 @@
     2.4 -/* TODO: try NOT using the v8086 interrupts to avoid the overhead */
     2.5  #include "mouse.h"
     2.6  #include "inttypes.h"
     2.7 -#include "dpmi.h"
     2.8  
     2.9  #define INTR	0x33
    2.10  
    2.11 @@ -10,63 +8,86 @@
    2.12  #define HIDE	2
    2.13  #define READ	3
    2.14  #define WRITE	4
    2.15 +#define PIXRATE	0xf
    2.16  
    2.17  #define XLIM	7
    2.18  #define YLIM	8
    2.19  
    2.20  int have_mouse(void)
    2.21  {
    2.22 -	struct dpmi_real_regs regs;
    2.23 -	memset(&regs, 0, sizeof regs);
    2.24 -	regs.eax = QUERY;
    2.25 -	dpmi_real_int(INTR, &regs);
    2.26 -	return regs.eax & 0xffff;
    2.27 +	uint16_t res = 0;
    2.28 +	_asm {
    2.29 +		mov eax, QUERY
    2.30 +		int INTR
    2.31 +		mov res, ax
    2.32 +	}
    2.33 +	return res;
    2.34  }
    2.35  
    2.36  void show_mouse(int show)
    2.37  {
    2.38 -	struct dpmi_real_regs regs;
    2.39 -	memset(&regs, 0, sizeof regs);
    2.40 -	regs.eax = show ? SHOW : HIDE;
    2.41 -	dpmi_real_int(INTR, &regs);
    2.42 +	uint16_t cmd = show ? SHOW : HIDE;
    2.43 +	_asm {
    2.44 +		mov ax, cmd
    2.45 +		int INTR
    2.46 +	}
    2.47  }
    2.48  
    2.49  int read_mouse(int *xp, int *yp)
    2.50  {
    2.51 -	struct dpmi_real_regs regs;
    2.52 -	memset(&regs, 0, sizeof regs);
    2.53 +	uint16_t x, y, state;
    2.54 +	_asm {
    2.55 +		mov eax, READ
    2.56 +		int INTR
    2.57 +		mov state, bx
    2.58 +		mov x, cx
    2.59 +		mov y, dx
    2.60 +	}
    2.61  
    2.62 -	regs.eax = READ;
    2.63 -	dpmi_real_int(INTR, &regs);
    2.64 -
    2.65 -	if(xp) *xp = regs.ecx & 0xffff;
    2.66 -	if(yp) *yp = regs.edx & 0xffff;
    2.67 -	return regs.ebx & 0xffff;
    2.68 +	if(xp) *xp = x;
    2.69 +	if(yp) *yp = y;
    2.70 +	return state;
    2.71  }
    2.72  
    2.73  void set_mouse(int x, int y)
    2.74  {
    2.75 -	struct dpmi_real_regs regs;
    2.76 -	memset(&regs, 0, sizeof regs);
    2.77 -
    2.78 -	regs.eax = WRITE;
    2.79 -	regs.ecx = x;
    2.80 -	regs.edx = y;
    2.81 -	dpmi_real_int(INTR, &regs);
    2.82 +	_asm {
    2.83 +		mov eax, WRITE
    2.84 +		mov ecx, x
    2.85 +		mov edx, y
    2.86 +		int INTR
    2.87 +	}
    2.88  }
    2.89  
    2.90  void set_mouse_limits(int xmin, int ymin, int xmax, int ymax)
    2.91  {
    2.92 -	struct dpmi_real_regs regs;
    2.93 -	memset(&regs, 0, sizeof regs);
    2.94 -	regs.eax = XLIM;
    2.95 -	regs.ecx = xmin;
    2.96 -	regs.edx = xmax;
    2.97 -	dpmi_real_int(INTR, &regs);
    2.98 +	_asm {
    2.99 +		mov eax, XLIM
   2.100 +		mov ecx, xmin
   2.101 +		mov edx, xmax
   2.102 +		int INTR
   2.103 +		mov eax, YLIM
   2.104 +		mov ecx, ymin
   2.105 +		mov edx, ymax
   2.106 +		int INTR
   2.107 +	}
   2.108 +}
   2.109  
   2.110 -	memset(&regs, 0, sizeof regs);
   2.111 -	regs.eax = YLIM;
   2.112 -	regs.ecx = ymin;
   2.113 -	regs.edx = ymax;
   2.114 -	dpmi_real_int(INTR, &regs);
   2.115 +void set_mouse_rate(int xrate, int yrate)
   2.116 +{
   2.117 +	_asm {
   2.118 +		mov ax, PIXRATE
   2.119 +		mov ecx, xrate
   2.120 +		mov edx, yrate
   2.121 +		int INTR
   2.122 +	}
   2.123  }
   2.124 +
   2.125 +void set_mouse_mode(enum mouse_mode mode)
   2.126 +{
   2.127 +	if(mode == MOUSE_GFX) {
   2.128 +		set_mouse_rate(1, 1);
   2.129 +	} else {
   2.130 +		set_mouse_rate(8, 16);
   2.131 +	}
   2.132 +}
     3.1 --- a/src/mouse.h	Mon Apr 07 06:04:11 2014 +0300
     3.2 +++ b/src/mouse.h	Mon Apr 07 08:05:06 2014 +0300
     3.3 @@ -1,9 +1,16 @@
     3.4  #ifndef MOUSE_H_
     3.5  #define MOUSE_H_
     3.6  
     3.7 -#define MOUSE_LEFT		1
     3.8 -#define MOUSE_RIGHT		2
     3.9 -#define MOUSE_MIDDLE	4
    3.10 +enum {
    3.11 +	MOUSE_LEFT		= 1,
    3.12 +	MOUSE_RIGHT		= 2,
    3.13 +	MOUSE_MIDDLE	= 4
    3.14 +};
    3.15 +
    3.16 +enum mouse_mode {
    3.17 +	MOUSE_GFX,
    3.18 +	MOUSE_TEXT
    3.19 +};
    3.20  
    3.21  #ifdef __cplusplus
    3.22  extern "C" {
    3.23 @@ -14,6 +21,8 @@
    3.24  int read_mouse(int *xp, int *yp);
    3.25  void set_mouse(int x, int y);
    3.26  void set_mouse_limits(int xmin, int ymin, int xmax, int ymax);
    3.27 +void set_mouse_rate(int xrate, int yrate);
    3.28 +void set_mouse_mode(enum mouse_mode mode);
    3.29  
    3.30  #ifdef __cplusplus
    3.31  }