Mouse.asm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. include_macros equ 1
  2. include_deb_mac equ 1
  3. include_struc equ 1
  4. include_flags equ 1
  5. include_error_codes equ 1
  6. include include.asm
  7. mice_file equ 60300
  8. start32data
  9. align 4
  10. mouse_data_start dd ?
  11. ; Mouse status variables
  12. amouse_x dd ? ;actual mouse coordinates
  13. amouse_y dd ?
  14. mouse_b dd ? ;used to check for repeat presses
  15. bmouse_b dd ? ;mouse button latch
  16. mouse_offset_x dd 0 ;for offsetting the mouse
  17. mouse_offset_y dd 0 ;+ve offsets only, mouse moves left or up
  18. ds_val dw ?
  19. dw ?
  20. mouse_stack db 1000 dup (?)
  21. mouse_stack_end dd ?
  22. ; Mouse data variables
  23. mouse_type2 dd ? ;number of current mouse
  24. mouse_data2 dd 0 ;pointer to mouse data (from mouse_type)
  25. mouse_width dd 6 ;mouse width and height
  26. mouse_height dd 6
  27. mouse_position dd ? ;current screen address of mouse
  28. mask_width dd 6 ;width on screen
  29. mask_height dd 6 ;height on screen
  30. saved_data dd 0 ;place for saved data
  31. mouse_flag dd 0 ;bit 0 set when in handler
  32. ;bit 1 set when screen data has been saved
  33. ;bit 2 set when we don't want to show mouse
  34. mice_data dd 0 ;address of mouse sprites
  35. object_mouse_data dd 0 ;address of object mouse sprites
  36. screen_segment dw ? ;descriptor for screen (0a000:0)
  37. ifdef with_replay
  38. _replay_flag dd 0
  39. endif
  40. mouse_data_end dd ?
  41. end32data
  42. start32code
  43. public restore_mouse_data
  44. init_mouse proc
  45. push es ;protect es from memlock's
  46. clear eax
  47. int 33h
  48. cmp ax,-1
  49. je found_mouse
  50. ifdef ignore_mouse
  51. jmp found_mouse
  52. endif
  53. program_error em_no_mouse
  54. found_mouse: mov [ds_val],ds ;save default ds
  55. mov ax,252bh ;lock the memory used by the mouse handler
  56. mov bx,501h
  57. mov ecx,offset mouse_handler
  58. mov edx,offset end_handler
  59. sub edx,ecx
  60. push cs
  61. pop es
  62. int 21h
  63. jc memlock_error
  64. mov ax,252bh ;lock the data too
  65. mov bx,501h
  66. mov ecx,offset mouse_data_start
  67. mov edx,offset mouse_data_end
  68. sub edx,ecx
  69. push ds
  70. pop es
  71. int 21h
  72. jc memlock_error
  73. ; Load the mouse sprite file and lock it
  74. mov eax,mice_file ;load it
  75. clear edx
  76. call load_file
  77. mov [mice_data],eax
  78. mov [mouse_data2],eax
  79. push eax ;lock the memory
  80. mov eax,mice_file
  81. call get_file_size
  82. mov edx,eax
  83. pop ecx
  84. mov bx,501h
  85. mov ax,252bh
  86. int 21h
  87. jc memlock_error
  88. ; Allocate data for the text mouse and lock it
  89. mov eax,[mice_data]
  90. movzx ebx,(s ptr[eax]).s_width
  91. movzx eax,(s ptr[eax]).s_height
  92. imul eax,ebx
  93. add eax,SIZE s
  94. push eax
  95. call my_malloc
  96. mov [saved_data],eax
  97. pop edx
  98. mov ecx,eax
  99. mov bx,501h
  100. mov ax,252bh
  101. int 21h
  102. jc memlock_error
  103. ; Load in the object mouse file
  104. mov eax,mice_file+1
  105. clear edx
  106. call load_file
  107. mov [object_mouse_data],eax
  108. mov [mouse_width],1
  109. mov [mouse_height],1
  110. ; Holy shit, what the hell is all this rubbish!
  111. mov ax,2509h ;Get system segments and selectors
  112. int 21h ;real mode cs in bx
  113. shl ebx,16 ;move cs: to top of ebx
  114. mov bx,offset __X386_CODESEG_16:mouse_init
  115. push ebx
  116. mov ax,250dh ;Get real mode call back address
  117. int 21h
  118. mov edi,eax ;Real mode call back address
  119. pop ebx ;real mode mouse routine
  120. ;mov edx,0ffffh ;mouse handler mask
  121. clear ecx ;no parameters
  122. mov ax,250eh ;call real mode mouse initialiser
  123. int 21h
  124. bts [system_flags],sf_mouse
  125. ; Set up some things for the mouse
  126. ; set horixontal range 640
  127. mov cx,0
  128. mov dx,639
  129. mouse_int 7
  130. ; set vertical range
  131. mov cx,0
  132. mov dx,198
  133. mouse_int 8
  134. ; Set up correct mouse coordinates
  135. mouse_int 3
  136. shr cx,1
  137. mov wpt [amouse_x],cx
  138. mov wpt [amouse_y],dx
  139. no_mouse: pop es
  140. ret
  141. memlock_error:: program_error em_internal_error
  142. init_mouse endp
  143. replace_mouse_cursors proc
  144. ; replace the mouse cursors from file eax
  145. mov edx,[object_mouse_data]
  146. call load_file
  147. ret
  148. replace_mouse_cursors endp
  149. ;--------------------------------------------------------------------------------------------------
  150. mouse_handler proc far
  151. pushf
  152. push eax
  153. push es
  154. mov ax,ss
  155. mov es,ax
  156. mov eax,esp
  157. mov ss,cs:[ds_val] ;use cs to load ss
  158. mov esp,offset mouse_stack_end
  159. push_all
  160. cld
  161. mov ds,cs:[ds_val] ;use cs to load ds
  162. ifdef with_screen_saver
  163. mov [sssss_count],0
  164. endif
  165. ; Check we have not interrupted the mouse handler
  166. bts [mouse_flag],mf_in_int
  167. jc mh_ret
  168. ; Store the current mouse position
  169. shr ecx,1 ;x coords are 0-639
  170. and ecx,7ffh
  171. and edx,7ffh
  172. cmp ecx,full_screen_width-1 ;-1 so some of mouse is always on screen
  173. jc xok ;-1 also avoid problems with moving too far
  174. mov ecx,full_screen_width-2 ; right on menu right arrow
  175. xok: mov [amouse_x],ecx
  176. cmp edx,full_screen_height-8
  177. jc yok
  178. mov edx,full_screen_height-1-8
  179. yok: mov [amouse_y],edx
  180. ; Two buttons, predictably the opposite way round to the amiga
  181. and ebx,3 ;strip any rubbish
  182. je no_butt
  183. sar ebx,1 ;swap buttons
  184. jnc no_butt
  185. bts ebx,1
  186. no_butt: ;If mouse button has changed check for new mouse press
  187. cmp ebx,[mouse_b]
  188. je button_waiting
  189. mov [mouse_b],ebx
  190. ; If no mouse button waiting for processing then check for a mouse button
  191. test [bmouse_b],0fh
  192. jne button_waiting
  193. test ebx,0fh
  194. je button_waiting
  195. mov [bmouse_b],ebx
  196. button_waiting: ;if we are in the middle of a flip then don't draw the mouse
  197. bt [mouse_flag],mf_no_update
  198. jc no_draw
  199. bts [system_flags],sf_mouse_stopped
  200. bt [system_flags],sf_test_disk
  201. ;jc no_draw
  202. btr [system_flags],sf_mouse_stopped
  203. call restore_mouse_data
  204. call draw_new_mouse
  205. no_draw: btr [mouse_flag],mf_in_int ;we are out of the handler
  206. mh_ret: pop_all
  207. mov esp,eax
  208. mov ax,es
  209. mov ss,ax
  210. pop es
  211. pop eax
  212. popf
  213. retf
  214. ;--------------------------------------------------------------------------------------------------
  215. calculate_mouse_values::
  216. ; Calculate some mouse values
  217. ; Include any offset
  218. mov eax,[amouse_y]
  219. sub eax,[mouse_offset_y]
  220. jnc not_neg_y
  221. clear eax
  222. not_neg_y: push eax ;save mouse_y including offset
  223. imul eax,eax,full_screen_width
  224. mov ebx,[amouse_x]
  225. sub ebx,[mouse_offset_x]
  226. jnc not_neg_x
  227. clear ebx
  228. not_neg_x: add eax,ebx ;ebx is mouse_x including offset
  229. mov [mouse_position],eax
  230. cherror eax,nc,64000,em_internal_error
  231. mov eax,[mouse_width]
  232. mov [mask_width],eax
  233. add eax,ebx ;[amouse_x]
  234. sub eax,full_screen_width
  235. jc no_mask_x
  236. sub [mask_width],eax
  237. no_mask_x: mov eax,[mouse_height]
  238. mov [mask_height],eax
  239. pop ebx ;restore mouse_y including offset
  240. add eax,ebx
  241. sub eax,full_screen_height-8
  242. jc no_mask_y
  243. sub [mask_height],eax
  244. no_mask_y: retn
  245. ;--------------------------------------------------------------------------------------------------
  246. ; save data under mouse
  247. save_mouse_data:: push ds
  248. push es
  249. mov ax,ds
  250. mov es,ax
  251. mov ds,[screen_segment]
  252. mov bx,es:[screen_segment]
  253. mov ds,bx
  254. mov esi,es:[mouse_position]
  255. mov edi,es:[saved_data]
  256. mov edx,es:[mask_height]
  257. sm_y_loop: push esi
  258. mov ecx,es:[mask_width]
  259. rep movsb
  260. pop esi
  261. add esi,full_screen_width
  262. floop edx,sm_y_loop
  263. pop es
  264. pop ds
  265. bts [mouse_flag],mf_saved
  266. retn
  267. ;--------------------------------------------------------------------------------------------------
  268. ; draw the mouse
  269. draw_mouse:: push es
  270. mov es,[screen_segment]
  271. mov esi,[mouse_data2]
  272. add esi,SIZE s
  273. mov edi,[mouse_position]
  274. mov edx,[mask_height]
  275. mouse_y_loop: push esi
  276. push edi
  277. mov ecx,[mask_width]
  278. mouse_x_loop: lodsb
  279. jife al,no_mpix
  280. mov es:[edi],al
  281. no_mpix: inc edi
  282. floop ecx,mouse_x_loop
  283. pop edi
  284. pop esi
  285. add esi,[mouse_width]
  286. add edi,full_screen_width
  287. floop edx,mouse_y_loop
  288. pop es
  289. retn
  290. ;--------------------------------------------------------------------------------------------------
  291. ; Restore data under mouse
  292. restore_mouse_data::
  293. btr [mouse_flag],mf_saved
  294. jnc rmd_ret
  295. push es
  296. mov es,[screen_segment]
  297. mov esi,[saved_data]
  298. mov edi,[mouse_position]
  299. mov edx,[mask_height]
  300. rm_loop: push edi
  301. mov ecx,[mask_width]
  302. rep movsb
  303. pop edi
  304. add edi,full_screen_width
  305. floop edx,rm_loop
  306. pop es
  307. rmd_ret: retn
  308. ;--------------------------------------------------------------------------------------------------
  309. draw_new_mouse:: call calculate_mouse_values
  310. call save_mouse_data
  311. call draw_mouse
  312. retn
  313. end_handler::
  314. mouse_handler endp
  315. draw_mouse_to_back_screen proc
  316. ; Draw the mouse to the back screen.
  317. bts [mouse_flag],mf_in_int
  318. ; First re-save the data under the back screen
  319. mov esi,[mouse_position]
  320. add esi,[backscreen]
  321. push esi
  322. mov edi,[saved_data]
  323. mov edx,[mask_height]
  324. save_loop: push esi
  325. mov ecx,[mask_width]
  326. rep movsb
  327. pop esi
  328. add esi,full_screen_width
  329. floop edx,save_loop
  330. ; Now draw mouse
  331. pop edi ;address to draw to
  332. mov esi,[mouse_data2]
  333. add esi,SIZE s
  334. mov edx,[mask_height]
  335. draw_loop: push esi
  336. push edi
  337. mov ecx,[mask_width]
  338. pix_loop: lodsb
  339. or al,al
  340. je no_pix
  341. mov bpt es:[edi],al
  342. no_pix: inc edi
  343. floop ecx,pix_loop
  344. pop edi
  345. add edi,full_screen_width
  346. pop esi
  347. add esi,[mouse_width]
  348. floop edx,draw_loop
  349. btr [mouse_flag],mf_in_int
  350. ret
  351. draw_mouse_to_back_screen endp
  352. restore_data_to_back_screen proc
  353. ; Restore saved data to the back screen
  354. mov esi,[saved_data]
  355. mov edi,[mouse_position]
  356. add edi,[backscreen]
  357. mov edx,[mask_height]
  358. restore_loop: push edi
  359. mov ecx,[mask_width]
  360. rep movsb
  361. pop edi
  362. add edi,full_screen_width
  363. floop edx,restore_loop
  364. btr [mouse_flag],mf_got_int
  365. jnc no_int
  366. call restore_mouse_data
  367. call draw_new_mouse
  368. no_int: ret
  369. restore_data_to_back_screen endp
  370. sprite_mouse proc
  371. ; eax is frame number of this mouse
  372. ; ebx is mouse x offset
  373. ; ecx is mouse y offset
  374. bts [mouse_flag],mf_in_int
  375. mov [mouse_type2],eax
  376. mov [mouse_offset_x],ebx
  377. mov [mouse_offset_y],ecx
  378. push esi
  379. push eax
  380. call restore_mouse_data
  381. pop eax
  382. mov esi,[mice_data]
  383. mul (s ptr[esi]).s_sp_size ;point to frame
  384. ; add eax,SIZE s
  385. add eax,esi
  386. mov [mouse_data2],eax
  387. movzx eax,(s ptr[esi]).s_width
  388. mov [mouse_width],eax
  389. movzx ebx,(s ptr[esi]).s_height
  390. mov [mouse_height],ebx
  391. call draw_new_mouse
  392. btr [mouse_flag],mf_in_int
  393. pop esi
  394. ret
  395. sprite_mouse endp
  396. remove_mouse proc
  397. ; Remove and stop the mouse
  398. bts [mouse_flag],mf_no_update
  399. call restore_mouse_data
  400. ret
  401. remove_mouse endp
  402. restore_mouse proc
  403. call draw_new_mouse
  404. btr [mouse_flag],mf_no_update
  405. ret
  406. restore_mouse endp
  407. ifdef with_replay
  408. replay_mouse proc
  409. bts [mouse_flag],mf_in_int
  410. mov [amouse_x],eax
  411. mov [amouse_y],ebx
  412. call restore_mouse_data
  413. call draw_new_mouse
  414. btr [mouse_flag],mf_in_int
  415. ret
  416. replay_mouse endp
  417. ;proc_start _set_replay__Nv
  418. ;
  419. ; bts [_replay_flag],rf_replay_on
  420. ;
  421. ;proc_end _set_replay__Nv
  422. endif
  423. end32code
  424. start16code
  425. call_back_addr dd ? ;Address of DOS32 call back device
  426. mouse_init proc far
  427. assume ds:__X386_CODESEG_16
  428. mov [call_back_addr],edi ;set call back
  429. push cs
  430. pop es
  431. mov ax,12
  432. mov dx,offset mouse_call
  433. mov cx,07fh ;dx ;mouse mask
  434. int 33h
  435. retf
  436. mouse_init endp
  437. mouse_call proc far
  438. db 66h ;push dword below
  439. push 0 ;push a dword zero for pointer to segments
  440. push 0 ;dummy space for protected mode cs
  441. ; masm can't be convinced to push a 32 bit offset so do it the hard way......
  442. db 66h ;size prefix
  443. db 68h ;push immediate
  444. dd offset mouse_handler ;offset of protected mode procedure
  445. call cs:call_back_addr ;call 32 bit function mous_call32
  446. add sp,10 ;pop parameters off stack
  447. ret ;return to mouse driver
  448. mouse_call endp
  449. end16code
  450. end
  451.