mouse.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /* $Id$
  2. * MegaZeux
  3. *
  4. * Copyright (C) 1996 Greg Janson
  5. * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
  6. * Copyright (C) 1999 Charles Goetzman
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. // Mouse routines. Converted from code by Dave Kirsch. Very simple w/text
  23. // cursor.
  24. #include "beep.h"
  25. #include <_null.h>
  26. #include "mouse.h"
  27. #include "data.h"
  28. #pragma inline
  29. char mousehidden=0;//Is the mouse hidden? (Additive)
  30. unsigned int mouseinstalled=0;//Is the mouse installed?
  31. char driver_activated=0;//Is our driver installed?
  32. volatile int mousex,mousey,mybutton;//Character position of mouse
  33. volatile int mbufin=0,mbufout=0;//Mouse buffer pointers
  34. char mousefreeze=0;//Is mouse frozen in place?
  35. mouse_info_rec mbuf[MOUSE_BUFFERSIZE];//Mouse event buffer
  36. unsigned int vseg;//Current segment of video ram.
  37. unsigned char old_color;
  38. unsigned char new_color;
  39. char saved=0;
  40. int oldmx,oldmy;
  41. int mouse_count=5000;//Countdown to pseudo-hide from non-activity.
  42. #define MK_FP( seg,ofs )( (void _seg * )( seg ) +( void near * )( ofs ))
  43. #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c))
  44. #define peekb(a,b) (*((char far*)MK_FP((a),(b))))
  45. #define POKEATTRIB(x,y,a) pokeb(vseg,(((y)*80+(x))<<1)+1,a)
  46. #define PEEKATTRIB(x,y) peekb(vseg,(((y)*80+(x))<<1)+1)
  47. #define POINTS *((unsigned char far *)0x00000485)
  48. //The new mouse handler.
  49. static void far mousehandler(void) {
  50. register int conditionmask;
  51. asm {
  52. push ds
  53. push ax
  54. mov ax,DGROUP
  55. mov ds,ax
  56. pop ax
  57. mov conditionmask,ax
  58. }
  59. mouse_count=5000;
  60. if(!mousefreeze) {
  61. //Save mouse info passed to us from driver
  62. asm {
  63. mov mousex, cx
  64. mov mousey, dx
  65. mov mybutton, bx //Gotta snag the mouse buttons now too. Spid
  66. }
  67. mousex>>=3;//Characters are 8 pixels wide
  68. if(POINTS==0) mousey=0;
  69. else mousey/=POINTS;//Scale mousey down
  70. //See if the mouse has moved.
  71. if(conditionmask&MOUSEMOVE) {
  72. if(saved) {
  73. POKEATTRIB(oldmx,oldmy,old_color);
  74. saved=0;
  75. }
  76. if(!mousehidden) {
  77. //Draw cursor
  78. old_color=PEEKATTRIB(mousex,mousey);
  79. /* _AX=old_color;
  80. asm rol al,3//Rotate it
  81. new_color=_AX;*/
  82. new_color=old_color^255;
  83. POKEATTRIB(mousex,mousey,new_color);//Write out new mouse cursor
  84. oldmx=mousex;
  85. oldmy=mousey;
  86. saved=1;
  87. }
  88. }
  89. }
  90. //Now, see if a mouse button was whacked
  91. if(conditionmask&~MOUSEMOVE) {
  92. if(((mbufin+1)%MOUSE_BUFFERSIZE)==mbufout) {//Buffer full?
  93. beep();
  94. }
  95. else {
  96. mbuf[mbufin].buttonstat=conditionmask&~MOUSEMOVE;
  97. mbuf[mbufin].cx=mousex;
  98. mbuf[mbufin].cy=mousey;
  99. mbufin=(mbufin+1)%MOUSE_BUFFERSIZE;
  100. }
  101. }
  102. asm pop ds
  103. }
  104. //Install the mouse routines.
  105. void m_init(void) {
  106. if(driver_activated) return;//Already done!
  107. asm {
  108. sub ax,ax//Mouse driver function 0 -- reset and detect
  109. int 33h
  110. mov mouseinstalled,ax
  111. }
  112. if(mouseinstalled) {//If a mouse is installed then activate driver
  113. mousefreeze++;//Make sure handler doesn't do things, yet
  114. vseg=0xb800;
  115. //Set up max x and y ranges
  116. asm {
  117. mov dx,639 //Pixels horizontally
  118. mov ax,7 //mouse driver function 7 -- set max x range
  119. sub cx,cx //Minimum range
  120. int 33h
  121. mov dx,349 //Pixels vertically
  122. mov ax,8 //mouse driver function 8 -- set max y range
  123. sub cx,cx //Minimum range
  124. int 33h
  125. }
  126. //Now install user routine
  127. asm {
  128. mov ax,cs
  129. mov es,ax
  130. mov dx,offset mousehandler
  131. //Setup up bits for calling routine */
  132. mov cx,31
  133. mov ax,12//Function 12 -- set user routine
  134. int 33h
  135. }
  136. mousex=mousey=0;
  137. asm {
  138. mov cx,mousex
  139. mov dx,mousey
  140. mov ax,4//mouse driver function 4 -- set mouse position */
  141. int 33h
  142. }
  143. m_show();
  144. mousefreeze--;
  145. driver_activated=1;
  146. }
  147. //Done!
  148. }
  149. //Save current mouse state to saved_mouse_* globals
  150. void m_snapshot(void) {
  151. saved_mouse_x = mousex;
  152. saved_mouse_y = mousey;
  153. saved_mouse_buttons = mybutton;
  154. }
  155. //Change the current video segment
  156. void m_vidseg(unsigned int newseg) {
  157. if(!driver_activated) return;
  158. if(!mousehidden) {
  159. m_hide();
  160. vseg=newseg;
  161. m_show();
  162. }
  163. else vseg=newseg;
  164. }
  165. //Hide the mouse cursor
  166. void m_hide(void) {
  167. if(!driver_activated) return;
  168. mousefreeze++;
  169. mousehidden++;
  170. if(saved) {
  171. POKEATTRIB(oldmx,oldmy,old_color);
  172. saved=0;
  173. }
  174. mousefreeze--;
  175. }
  176. //Show the mouse cursor
  177. void m_show(void) {
  178. if(!driver_activated) return;
  179. mousefreeze++;
  180. if(mousehidden) mousehidden--;
  181. else {
  182. mousefreeze--;
  183. return;
  184. }
  185. if(mousehidden) {
  186. mousefreeze--;
  187. return;
  188. }
  189. //Draw mouse cursor
  190. old_color=PEEKATTRIB(mousex,mousey);
  191. /* _AX=old_color;
  192. asm rol al,3
  193. new_color=_AX;*/
  194. new_color=old_color^255;
  195. POKEATTRIB(mousex,mousey,new_color);
  196. oldmx=mousex;
  197. oldmy=mousey;
  198. saved=1;
  199. mousefreeze--;
  200. }
  201. //Move the mouse cursor
  202. void m_move(int newx,int newy) {
  203. if(!driver_activated) return;
  204. mousefreeze++;
  205. //Convert x/y to pixels
  206. mousex=newx;
  207. mousey=newy;
  208. newx*=8;
  209. newy*=14;
  210. m_hide();
  211. asm {
  212. mov cx,newx
  213. mov dx,newy
  214. mov ax,4//mouse driver function 4 -- set mouse position */
  215. int 33h
  216. }
  217. m_show();
  218. mousefreeze--;
  219. }
  220. //Returns non-0 if there is something in the mouse buffer
  221. char m_check(void) {
  222. return mbufin!=mbufout;
  223. }
  224. //Grab a copy of the top event
  225. void m_preview(mouse_info_rec *mir) {
  226. if(!driver_activated) return;
  227. if(mbufin!=mbufout)
  228. *mir=mbuf[mbufout];
  229. else {
  230. //Nothing to pull, just report mouse position
  231. mir->cx=mousex;
  232. mir->cy=mousey;
  233. mir->buttonstat=0;
  234. }
  235. }
  236. //Grab the actual top event
  237. void m_get(mouse_info_rec *mir) {
  238. if(!driver_activated) return;
  239. if(mbufin!=mbufout) {
  240. if(mir!=NULL) *mir=mbuf[mbufout];
  241. mbufout=(mbufout+1)%MOUSE_BUFFERSIZE;
  242. }
  243. else {
  244. //Nothing to pull, just report mouse position */
  245. mir->cx=mousex;
  246. mir->cy=mousey;
  247. mir->buttonstat=0;
  248. }
  249. }
  250. //Uninstall the mouse routines
  251. void m_deinit(void) {
  252. if(!driver_activated) return;
  253. m_hide();
  254. asm {
  255. sub ax,ax
  256. int 33h
  257. }
  258. driver_activated=0;
  259. }
  260. //Get bits of button info
  261. int m_buttonstatus(void) {
  262. int bits;
  263. if(!driver_activated) return 0;
  264. asm {
  265. mov ax,3
  266. int 33h
  267. mov bits,bx
  268. }
  269. return bits;
  270. }