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(®s, 0, sizeof regs); 2.24 - regs.eax = QUERY; 2.25 - dpmi_real_int(INTR, ®s); 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(®s, 0, sizeof regs); 2.40 - regs.eax = show ? SHOW : HIDE; 2.41 - dpmi_real_int(INTR, ®s); 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(®s, 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, ®s); 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(®s, 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, ®s); 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(®s, 0, sizeof regs); 2.94 - regs.eax = XLIM; 2.95 - regs.ecx = xmin; 2.96 - regs.edx = xmax; 2.97 - dpmi_real_int(INTR, ®s); 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(®s, 0, sizeof regs); 2.111 - regs.eax = YLIM; 2.112 - regs.ecx = ymin; 2.113 - regs.edx = ymax; 2.114 - dpmi_real_int(INTR, ®s); 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 }