mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 05:49:19 +00:00
380 lines
10 KiB
Plaintext
380 lines
10 KiB
Plaintext
;
|
||
; File: Mouse.a
|
||
;
|
||
; Contains: routines related to the mouse
|
||
;
|
||
; Written by: Steve Horowitz & Francis Stanbach
|
||
;
|
||
; Copyright: © 1990 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <7> 1/13/91 dba (KIP) add fix for old key repeat bugs in the Macintosh Plus ROM;
|
||
; specifically, be sure that KeyThresh and KeyRepThresh do not
|
||
; have 0s in them
|
||
; <6> 7/10/90 dba Oops! Frank forgot to export MTable and he didn’t test it (my
|
||
; fault, I was with him at the time).
|
||
; <5> 7/10/90 fjs more cleanup related to Darin
|
||
; <4> 5/19/90 fjs more cleanup related to Darin
|
||
; <3> 5/16/90 dba work on it more (tag-team programming)
|
||
; <2> 5/16/90 fjs add more comments for Captain Van Eye Patch
|
||
; <1> 5/16/90 fjs Annette sure was cute
|
||
; 5/15/90 fjs That's right I'm writing this code
|
||
;
|
||
; To Do:
|
||
;
|
||
|
||
load 'StandardEqu.d'
|
||
include 'LinkedPatchMacros.a'
|
||
|
||
MGlobals record 0 ; mouse mapping globals data structure
|
||
Count ds.w 1 ; word: number of valid error deltas
|
||
MaxCnt ds.w 1 ; word: limit on number of error deltas
|
||
Err7 ds.w 1 ; word: time-7 error magnitude
|
||
Err6 ds.w 1 ; word: time-6 error magnitude
|
||
Err5 ds.w 1 ; word: time-5 error magnitude
|
||
Err4 ds.w 1 ; word: time-4 error magnitude
|
||
Err3 ds.w 1 ; word: time-3 error magnitude
|
||
Err2 ds.w 1 ; word: time-2 error magnitude
|
||
Err1 ds.w 1 ; word: time-1 error magnitude
|
||
Error ds.w 1 ; word: accumulated error
|
||
GSize equ * ; size of regular globals
|
||
Table ds.b 8 ; mickey bytes table
|
||
TotalSize equ * ; size
|
||
endr
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; initialize the mouse mapping table
|
||
|
||
PlusMouseInit InstallProc (Plus)
|
||
import MickeyBytesHelper
|
||
import MTable
|
||
|
||
; since the Plus boot code sometimes leaves KeyThresh and KeyRepThresh 0, check for that case.
|
||
|
||
tst.w KeyRepThresh
|
||
bne.s KeyRepThreshOK
|
||
move.w #$48*2,KeyRepThresh ; stuff same value used by modern boot code
|
||
KeyRepThreshOK
|
||
|
||
tst.w KeyThresh
|
||
bne.s KeyThreshOK
|
||
move.w #$1FFF<<2,KeyThresh ; stuff same value used by modern boot code
|
||
KeyThreshOK
|
||
|
||
lea MTable,a2 ; load pointer to table in a2
|
||
|
||
jmp MickeyBytesHelper
|
||
|
||
endproc
|
||
|
||
|
||
ADBMouseInit InstallProc (SE,II,Portable,IIci)
|
||
import MickeyBytesHelper
|
||
|
||
move.l MickeyBytes,a2 ; get ptr to globals
|
||
add #MGlobals.Table,a2 ; point past globals to table
|
||
|
||
jmp MickeyBytesHelper
|
||
|
||
endproc
|
||
|
||
|
||
MickeyBytesHelper proc
|
||
|
||
; get the value in PRAM
|
||
|
||
moveq #$78,d0 ; mask off the appropriate bits
|
||
and.b SPVolCtl,d0 ; of value from PRAM
|
||
lsr.b #3,d0 ; gets resource # to load
|
||
|
||
; attempt to get the resource from system file
|
||
|
||
subq #4,sp ; room for ResHandle
|
||
move.l #'mcky',-(sp) ; Mickey Mouse Tracking bytes
|
||
move.w d0,-(sp) ; gives us our ID
|
||
_GetResource
|
||
move.l (sp)+,d0 ; get handle into d0
|
||
beq.s noBytes ; we didn't get one, use default
|
||
|
||
move.l d0,a0 ; get handle in a0
|
||
move.l (a0),a0 ; source = mickey bytes
|
||
bra.s gotMickey ; install the bytes (should this be 'rts' ?)
|
||
|
||
noBytes
|
||
lea default, a0 ; use the default bytes
|
||
|
||
; make it default to 2 if there is no resource
|
||
|
||
and.b #87,SPVolCtl ; mask off old setting
|
||
ori.b #(2<<3),SPVolCtl ; and OR it in PRAM
|
||
|
||
gotMickey
|
||
|
||
move.l (a0)+,(a2)+ ; move the bytes in
|
||
move.l (a0),(a2)
|
||
|
||
rts
|
||
|
||
default dc.b 4, 10, 15, 255, 255, 255, 255, 255
|
||
|
||
ENDPROC
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————————————————
|
||
; Mouse Mapping code for Mac Plus
|
||
|
||
ROMs Plus
|
||
MakePatch MapCode,jCrsrTask
|
||
|
||
MouseMapping PROC
|
||
EXPORT MapCode
|
||
EXPORT MTable
|
||
|
||
; This signature is so that the Mouse control panel can recognize this lovely CrsrTask.
|
||
; It is probably completely unnecessary; at the very least we could do something shorter.
|
||
|
||
STRING ASIS
|
||
Signature dc.b 'Horowitz' ; isn’t that special
|
||
|
||
Globals
|
||
|
||
; define these as constants instead of storage so that you can give them
|
||
; initial values without explicitly initializing them. Is this cheezy or
|
||
; genius ? <15may90 fjs>
|
||
|
||
mCount dc.w 1 ; word: number of valid error deltas
|
||
mMaxCnt dc.w 1 ; word: limit on number of error deltas
|
||
mErr7 dc.w 0 ; word: time-7 error magnitude
|
||
mErr6 dc.w 0 ; word: time-6 error magnitude
|
||
mErr5 dc.w 0 ; word: time-5 error magnitude
|
||
mErr4 dc.w 0 ; word: time-4 error magnitude
|
||
mErr3 dc.w 0 ; word: time-3 error magnitude
|
||
mErr2 dc.w 0 ; word: time-2 error magnitude
|
||
mErr1 dc.w 0 ; word: time-1 error magnitude
|
||
mError dc.w 0 ; word: accumulated error
|
||
|
||
mTable dc.b 0,0,0,0,0,0,0,0 ; mickey bytes table (some day put default values here?)
|
||
|
||
with MGlobals
|
||
|
||
MapCode
|
||
tst.b CrsrNew ; Mouse changed?
|
||
beq Done ; No … return
|
||
tst.b CrsrBusy ; Cursor locked?
|
||
bne Done ; Yes … return
|
||
|
||
tst.b CrsrCouple ; Cursor coupled to mouse?
|
||
beq NoComp ; No … skip computation <DSV>
|
||
|
||
move.w MTemp+H,D0 ; Find ∆Mx
|
||
sub.w RawMouse+H,D0
|
||
|
||
move.w MTemp+V,d1 ; Find ∆My
|
||
sub.w RawMouse+V,d1
|
||
|
||
move.w d0,d2 ; x := |∆Mx|
|
||
bge.s AbsX
|
||
neg.w d2
|
||
AbsX
|
||
|
||
move.w d1,d3 ; y := |∆My|
|
||
bge.s AbsY
|
||
neg.w d3
|
||
AbsY
|
||
|
||
cmp.w d2,d3 ; d3 := magnitude(x,y)
|
||
bls.s magdone
|
||
exg d2,d3
|
||
MagDone
|
||
ASR.w #1,d3
|
||
add.w d2,d3
|
||
|
||
; *** BEGIN NEW ***
|
||
|
||
lea Globals,a0 ; Get my globals
|
||
|
||
bne.s DoComp ; <03/07/87 EMT>
|
||
move.w #1,Count(a0) ; No hits <03/07/87 EMT>
|
||
clr.w Error(a0) ; No errors <03/07/87 EMT>
|
||
BRA DoPin ; Redraw the cursor <03/07/87 EMT>
|
||
|
||
DoComp ; <03/07/87 EMT>
|
||
moveM.l d4-d5,-(A7) ; Save off registers
|
||
move.w Count(a0),d4 ; d4 is the number of samples
|
||
cmp.w MaxCnt(a0),d4 ; Is Count less than MaxCnt
|
||
bge.s CountOK
|
||
add.w #1,Count(a0) ; Yes … we will have one more error
|
||
|
||
CountOK
|
||
|
||
move.w d3,d5 ; Magnitude at current time
|
||
|
||
move.w d4,d2 ; Get Count
|
||
sub.w #1,d2 ; Index into JTab
|
||
ASL.w #1,d2 ; REQUIRES bra.s’s IN JUMP TAbleS
|
||
JMP JTab(PC,d2.w) ; Jump to the right code per Count
|
||
|
||
JTab bra.s E1 ; Count = 1
|
||
bra.s E2 ; Count = 2
|
||
bra.s E3 ; Count = 3
|
||
bra.s E4 ; Count = 4
|
||
bra.s E5 ; Count = 5
|
||
bra.s E6 ; Count = 6
|
||
bra.s E7 ; Count = 7
|
||
; *** bra.s E8 ; Count = 8 ***
|
||
|
||
|
||
E8 add.w Err7(a0),d5 ; Accumulate time-7 magnitude
|
||
|
||
E7 add.w Err6(a0),d5 ; Accumulate time-6 magnitude
|
||
move.w Err6(a0),Err7(a0) ; Shift out time-6 magnitude
|
||
|
||
E6 add.w Err5(a0),d5 ; Accumulate time-5 magnitude
|
||
move.w Err5(a0),Err6(a0) ; Shift out time-5 magnitude
|
||
|
||
E5 add.w Err4(a0),d5 ; Accumulate time-4 magnitude
|
||
move.w Err4(a0),Err5(a0) ; Shift out time-4 magnitude
|
||
|
||
E4 add.w Err3(a0),d5 ; Accumulate time-3 magnitude
|
||
move.w Err3(a0),Err4(a0) ; Shift out time-3 magnitude
|
||
|
||
E3 add.w Err2(a0),d5 ; Accumulate time-2 magnitude
|
||
move.w Err2(a0),Err3(a0) ; Shift out time-2 magnitude
|
||
|
||
E2 add.w Err1(a0),d5 ; Accumulate time-1 magnitude
|
||
move.w Err1(a0),Err2(a0) ; Shift out time-1 magnitude
|
||
|
||
E1 move.w d3,Err1(a0) ; Shift out current magnitude
|
||
|
||
move.w d4,d2 ; Round up the divide
|
||
ASR.w #1,d2 ; by half the denominator
|
||
add.w d2,d5
|
||
EXT.l d5 ; Set up for the divide
|
||
DIVU d4,d5 ; Find the average magnitude
|
||
|
||
move.w d3,d4 ; Get the original magnitude
|
||
sub.w d5,d3 ; Find distance to average magnitude
|
||
add.w Error(a0),d3 ; add on the accumulated error
|
||
cmp.w #-1,d3 ; Define -1 div 2 = 0
|
||
bne.s DivOK
|
||
clr.w d3
|
||
|
||
DivOK ASR.w #1,d3 ; Get half of it
|
||
move.w d3,Error(a0) ; Update it
|
||
add.w d5,d3 ; Desired mag is average+Error
|
||
|
||
cmp.w #255,d5 ; mag := MAX(mag,255)
|
||
BLS.s MaxDone
|
||
move.b #255,d5
|
||
MaxDone
|
||
|
||
lea MTable,a0 ; address Table
|
||
clr.w d2 ; i := 0
|
||
|
||
Search
|
||
add.b #1,d2 ; repeat
|
||
cmp.b (a0)+,d5 ; i := i+1
|
||
BHI.s Search ; until mag ≤ Table[i]
|
||
|
||
muls d2,d3 ; d4 := i*(Mag(∆M)+Error)
|
||
|
||
muls d3,d0 ; ∆Cx := (∆Mx*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
divs d4,d0 ; <<<<<< d3 >>>>>>>
|
||
|
||
muls d3,d1 ; ∆Cy := (∆My*i*(Mag(∆M)+Error))/Mag(∆M)
|
||
divs d4,d1 ; <<<<<< d3 >>>>>>>
|
||
|
||
moveM.l (A7)+,d4-d5 ; Restore registers
|
||
|
||
; *** END NEW ***
|
||
|
||
add.w d0,RawMouse+H ; Update raw mouse location
|
||
add.w d1,RawMouse+V
|
||
|
||
DoPin ; <03/07/87 EMT>
|
||
lea CrsrPin,a0 ; Bounding rect for cursor
|
||
move.l RawMouse,d0 ; Pin mouse inside rect
|
||
BSR.s PinGuts
|
||
|
||
move.l d0,RawMouse ; Update cursor locations
|
||
move.l d0,MTemp
|
||
|
||
AND.l MouseMask,d0 ; Do jerky masking to drop low bits
|
||
move.l MouseOffset,d1 ; Get the offset
|
||
beq.s SkipPin ; Skip 2nd pin if not
|
||
add.l d1,d0 ; Do jerky offset
|
||
BSR.s PinGuts ; Pin mouse inside rect again
|
||
SkipPin
|
||
move.l d0,Mouse ; Actual mouse location
|
||
|
||
Repaint
|
||
TST.b CrsrObscure ; Unpaint the cursor
|
||
bne.s Unpainted
|
||
_HideCursor ; Hide the cursor
|
||
Unpainted
|
||
|
||
clr.b CrsrNew ; Cursor is fresh
|
||
clr.b CrsrObscure ; Cursor is not obscured
|
||
_ShowCursor ; Repaint the cursor
|
||
|
||
; *** BEGIN NEW ***
|
||
|
||
rts ; Goodbye
|
||
|
||
|
||
|
||
Done
|
||
lea Globals,a0 ; Get my globals
|
||
move.w #1,Count(a0) ; No hits
|
||
clr.w Error(a0) ; No errors
|
||
rts ; Goodbye
|
||
|
||
|
||
NoComp
|
||
lea Globals,a0 ; Get my globals
|
||
move.w #1,Count(a0) ; No hits
|
||
clr.w Error(a0) ; No errors
|
||
bra.s Repaint ; Update the cursor
|
||
|
||
; *** END NEW ***
|
||
|
||
|
||
; PinGuts limits the point in d0 to the bounding rectangle pointed to by a0.
|
||
|
||
; use the ROM instead, since it even works better, but only when you are really sure!
|
||
; (Darin)
|
||
|
||
PinGuts
|
||
cmp.w Left(a0),d0 ; Check left side
|
||
bge.s LeftOK
|
||
move.w Left(a0),d0
|
||
|
||
LeftOK
|
||
cmp.w Right(a0),d0 ; Check right side
|
||
ble.s RightOK
|
||
move.w Right(a0),d0
|
||
sub.w #1,d0
|
||
|
||
RightOK
|
||
swap d0 ; Deal with vertical coord
|
||
cmp.w Top(a0),d0 ; Check top
|
||
bge.s TopOK
|
||
move.w Top(a0),d0
|
||
|
||
TopOK
|
||
cmp.w Bottom(a0),d0 ; Check bottom
|
||
ble.s BotOK
|
||
move.w Bottom(a0),d0
|
||
sub.w #1,d0
|
||
BotOK
|
||
swap d0
|
||
|
||
rts
|
||
|
||
endwith
|
||
endproc
|
||
|
||
|
||
end
|