unit FlyGlider; interface uses Palettes, Globals, Utilities, Drawing, ObjectStuff; procedure ResetGlider; procedure ExtractEventRects; procedure ReadyRoom; procedure FlyGlider; var nObjects: Integer; timeIs: LongInt; testRoom: roomData; {=================================} implementation {=================================} procedure CenterMouse; const MBState = $172; MTemp = $828; RawMouse = $82C; Mouse = $830; CrsrNew = $8CE; CrsrCouple = $8CF; Couple = $FF; Uncouple = $00; var center: Point; lowGlob: Integer; lowMem: Ptr; pointPtr: ^Point; begin SetPt(center, 256, 171); lowMem := Pointer(rawMouse); pointPtr := @lowMem^; pointPtr^ := center; lowMem := Pointer(MTemp); pointPtr := @lowMem^; pointPtr^ := center; lowMem := Pointer(CrsrNew); lowMem^ := $FFFF; end; {=================================} procedure ReadyGlider; var mousePt: Point; dummyLong, timeToStop: LongInt; tempRect: Rect; begin with theGlider do begin bands := 0; forVel := 4; energy := 0; mode := fadingIn; phase := 0; isForward := TRUE; isRight := TRUE; if (isRight) then SetRect(destRect, 0, 40, 48, 60) else SetRect(destRect, 464, 40, 512, 60); oldRect := destRect; wholeRect := destRect; srcNum := 0; mass := currMass; end; lifeNormal := FALSE; PenNormal; PenMode(patXOr); FrameRect(theGlider.destRect); repeat until not Button; repeat with theGlider do begin FrameRect(oldRect); GetMouse(mousePt); SetRect(destRect, -24, -10, 24, 10); OffsetRect(destRect, mousePt.h, mousePt.v); FrameRect(destRect); oldRect := destRect; end; until Button; FrameRect(theGlider.oldRect); tempRect := theGlider.oldRect; InsetRect(tempRect, -1, -1); FrameRect(tempRect); with theGlider do begin oldRect := destRect; wholeRect := destRect; shadoDest := destRect; shadoDest.top := floorVert; shadoDest.bottom := floorVert + 11; oldShado := shadoDest; wholeShado := shadoDest; touchRect := destRect; InsetRect(touchRect, 10, 5); if (inColor) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, glideRct[srcNum], glideRct[srcNum], destRect) else CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, glideRct[srcNum], glideRct[srcNum], destRect) end; timeToStop := TickCount + 120; repeat SpinBall; Delay(2, dummyLong); until (TickCount > timeToStop); FrameRect(tempRect); end; {=================================} procedure ExtractEventRects; var index, tempInt, tempNum: Integer; tempRect: Rect; {-------------------------} procedure SetUpGrease; begin nCycleObs := nCycleObs + 1; with testRoom.theObjects[index] do begin if (isOn) then begin eventRect[index] := boundRect; with cycleObjects[nCycleObs] do begin kindIs := grease; tiedTo := index; wholeRect := eventRect[index]; oldRect := wholeRect; reset := 0; {phase=not spilled} accel := grease; {graphic # to display} velocity := wholeRect.right;{current length of spill} position := amount; {full length of spill} end; end else begin eventRect[index].left := boundRect.right; eventRect[index].bottom := boundRect.bottom; eventRect[index].right := amount; eventRect[index].top := boundRect.bottom - 4; with cycleObjects[nCycleObs] do begin kindIs := grease; tiedTo := index; wholeRect := boundRect; oldRect := wholeRect; reset := 999; {phase=spilled} accel := 59; {graphic # to display} velocity := amount; {current length of spill} position := amount; {length of spill} end; end; end; end; {-------------------------} procedure FrameOutlet; begin nCycleObs := nCycleObs + 1; eventRect[index] := testRoom.theObjects[index].boundRect; with cycleObjects[nCycleObs] do begin kindIs := outlet; tiedTo := index; eventKind[tiedTo, 1] := 0; accel := 25; wholeRect := testRoom.theObjects[index].boundRect; oldRect := wholeRect; reset := testRoom.theObjects[index].amount; position := TickCount; end; end; {-------------------------} procedure FrameCandle; begin nCycleObs := nCycleObs + 1; with testRoom.theObjects[index] do begin tempInt := (boundRect.right + boundRect.left) div 2; SetRect(eventRect[index], tempInt - 12, amount, tempInt + 4, boundRect.top); end; with cycleObjects[nCycleObs] do begin wholeRect := testRoom.theObjects[index].boundRect; wholeRect.bottom := wholeRect.top; wholeRect.top := wholeRect.bottom - 12; wholeRect.left := wholeRect.left + 5; wholeRect.right := wholeRect.left + 16; oldRect := wholeRect; kindIs := candle; position := DoRandom(3) + 48; end; end; {-------------------------} procedure FrameDrip; var objectType: Integer; begin nCycleObs := nCycleObs + 1; eventRect[index] := testRoom.theObjects[index].boundRect; with cycleObjects[nCycleObs] do begin kindIs := drip; tiedTo := index; holdRect := testRoom.theObjects[index].boundRect; wholeRect := holdRect; oldRect := wholeRect; reset := testRoom.theObjects[index].amount * 32; accel := 12; position := holdRect.bottom * 32; velocity := 0; phase := 53; with testRoom.theObjects[index] do if (inColor) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(virginCPtr^.portPixMap^)^, srcRect[objectIs], srcRect[objectIs], boundRect) else CopyMask(offPlayerMap, offMaskMap, offVirginMap, srcRect[objectIs], srcRect[objectIs], boundRect); end; end; {-------------------------} procedure ReadyToast; begin nCycleObs := nCycleObs + 1; with testRoom.theObjects[index] do begin tempInt := boundRect.left + 3; tempNum := boundRect.bottom - 3; SetRect(eventRect[index], 0, 0, 32, 31); OffsetRect(eventRect[index], tempInt, tempNum); SetRect(tempRect, tempInt, amount, tempInt + 32, boundRect.top); if (inColor) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(virginCPtr^.portPixMap^)^, srcRect[objectIs], srcRect[objectIs], boundRect) else CopyMask(offPlayerMap, offMaskMap, offVirginMap, srcRect[objectIs], srcRect[objectIs], boundRect); end; toastRgn := NewRgn; RectRgn(toastRgn, tempRect); hasToast := TRUE; with cycleObjects[nCycleObs] do begin phase := 60; kindIs := toastr; tiedTo := index; wholeRect := eventRect[index]; oldRect := wholeRect; reset := tempNum * 32; accel := 8; position := reset; tempInt := (testRoom.theObjects[index].amount + 32) * 32; velocity := 0; repeat velocity := velocity + accel; tempInt := tempInt + velocity; until (tempInt > reset); velocity := -velocity; end; end; {-------------------------} procedure FrameBall; begin nCycleObs := nCycleObs + 1; eventRect[index] := testRoom.theObjects[index].boundRect; with cycleObjects[nCycleObs] do begin kindIs := ball; tiedTo := index; wholeRect := testRoom.theObjects[index].boundRect; oldRect := wholeRect; reset := testRoom.theObjects[index].boundRect.bottom * 32; accel := 8; position := reset; tempInt := (testRoom.theObjects[index].amount + 32) * 32; velocity := 0; repeat velocity := velocity + accel; tempInt := tempInt + velocity; until (tempInt > reset); velocity := -velocity; end; end; {-------------------------} procedure ReadyFish; begin nCycleObs := nCycleObs + 1; with testRoom.theObjects[index] do begin tempInt := boundRect.left + 8; tempNum := boundRect.top + 24; SetRect(eventRect[index], 0, 0, 16, 16); {fish rectangle} OffsetRect(eventRect[index], tempInt, tempNum); if (inColor) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(virginCPtr^.portPixMap^)^, srcRect[objectIs], srcRect[objectIs], boundRect) else CopyMask(offPlayerMap, offMaskMap, offVirginMap, srcRect[objectIs], srcRect[objectIs], boundRect); end; with cycleObjects[nCycleObs] do begin phase := 69; {# of fish rect} kindIs := fshBwl; tiedTo := index; wholeRect := eventRect[index]; oldRect := wholeRect; reset := tempNum * 32; accel := 8; position := reset; tempInt := (testRoom.theObjects[index].amount + 32) * 32; velocity := 0; repeat velocity := velocity + accel; tempInt := tempInt + velocity; until (tempInt > reset); velocity := -velocity; end; end; {-------------------------} procedure ReadyTea; begin nCycleObs := nCycleObs + 1; with testRoom.theObjects[index] do begin tempInt := boundRect.left; tempNum := boundRect.top; SetRect(eventRect[index], tempInt - 128, tempNum - 128, tempInt, tempNum); if (eventRect[index].top < ceilingVert) then eventRect[index].top := ceilingVert; if (eventRect[index].left < 0) then eventRect[index].left := 0; end; with cycleObjects[nCycleObs] do begin phase := 0; kindIs := teaKtl; tiedTo := index; SetRect(wholeRect, 0, 0, 0, 0); oldRect := wholeRect; position := testRoom.theObjects[index].amount; reset := position + DoRandom(120); end; end; {-------------------------} procedure FrameWindow; begin nObjects := nObjects - 1; end; {-------------------------} procedure FrameMirror; begin nObjects := nObjects - 1; with testRoom.theObjects[index] do tempRect := boundRect; InsetRect(tempRect, 5, 5); end; {-------------------------} begin windowOpen := FALSE; if (testRoom.conditionCode = 2) then lightsOut := TRUE else lightsOut := FALSE; if (testRoom.conditionCode = 1) then airOut := TRUE else airOut := FALSE; nCycleObs := 0; nObjects := testRoom.numberOObjects; tempNum := nObjects; for index := 1 to tempNum do with testRoom.theObjects[index] do begin case objectIs of table..obsRct: eventRect[index] := boundRect; flrVnt: begin tempInt := (boundRect.right + boundRect.left) div 2; SetRect(eventRect[index], tempInt - 8, amount, tempInt + 8, floorVert); end; celVnt: begin tempInt := (boundRect.right + boundRect.left) div 2; SetRect(eventRect[index], tempInt - 8, ceilingVert, tempInt + 8, amount); end; celDct: if (isOn) then begin tempInt := (boundRect.right + boundRect.left) div 2; SetRect(eventRect[index], tempInt - 8, ceilingVert, tempInt + 8, amount); end else begin eventRect[index] := boundRect; eventRect[index].bottom := eventRect[index].top + 8; end; candle: FrameCandle; lftFan: SetRect(eventRect[index], amount, boundRect.top + 10, boundRect.left, boundRect.top + 30); ritFan: SetRect(eventRect[index], boundRect.right, boundRect.top + 10, amount, boundRect.top + 30); clock, paper: eventRect[index] := boundRect; grease: SetUpGrease; bnsRct..rbrBnd: eventRect[index] := boundRect; litSwt, thermo, pwrSwt: eventRect[index] := boundRect; shredr: begin eventRect[index] := boundRect; eventRect[index].top := eventRect[index].top - 4; eventRect[index].bottom := eventRect[index].bottom - 12; end; outlet: FrameOutlet; guitar: with boundRect do SetRect(eventRect[index], left + 36, top + 24, left + 38, bottom - 56); ball: FrameBall; drip: FrameDrip; toastr: ReadyToast; fshBwl: ReadyFish; teaKtl: ReadyTea; window: FrameWindow; paintg: nObjects := nObjects - 1; mirror: FrameMirror; basket, macTsh: eventRect[index] := boundRect; upStar: with boundRect do SetRect(eventRect[index], left + 32, top, right - 32, top + 8); dnStar: with boundRect do SetRect(eventRect[index], left + 32, bottom - 8, right - 32, bottom); otherwise eventRect[index] := nullRect; end; {case} eventKind[index, 1] := 0; case objectIs of table, shelf, books, cabnet, obsRct, drip, toastr, ball, fshBwl, basket, macTsh: eventKind[index, 0] := crashIt; extRct: eventKind[index, 0] := moveIt; flrVnt: eventKind[index, 0] := liftIt; celVnt: eventKind[index, 0] := dropIt; celDct: if (isOn) then eventKind[index, 0] := dropIt else begin eventKind[index, 0] := moveIt; eventKind[index, 1] := extra; end; candle: begin eventKind[index, 0] := burnIt; eventKind[index, 1] := boundRect.bottom - 48; end; lftFan: if (isOn) then eventKind[index, 0] := turnItLeft else eventKind[index, 0] := ignoreIt; ritFan: if (isOn) then eventKind[index, 0] := turnItRight else eventKind[index, 0] := ignoreIt; clock: begin eventKind[index, 0] := awardIt; eventKind[index, 1] := amount; if (amount < 1) then eventRect[index] := nullRect; end; paper: begin eventKind[index, 0] := extraIt; eventKind[index, 1] := amount; if (amount < 1) then eventRect[index] := nullRect; end; grease: if (isOn) then eventKind[index, 0] := spillIt else eventKind[index, 0] := slideIt; bnsRct: begin eventKind[index, 0] := trickIt; eventKind[index, 1] := amount; if (amount < 1) then eventRect[index] := nullRect; end; battry: begin eventKind[index, 0] := energizeIt; eventKind[index, 1] := amount; if (amount < 1) then eventRect[index] := nullRect; end; rbrBnd: begin eventKind[index, 0] := bandIt; eventKind[index, 1] := amount; if (amount < 1) then eventRect[index] := nullRect; end; litSwt: eventKind[index, 0] := lightIt; outlet: eventKind[index, 0] := zapIt; thermo: eventKind[index, 0] := airOnIt; shredr: if (isOn) then eventKind[index, 0] := shredIt else eventKind[index, 0] := ignoreIt; pwrSwt: begin eventKind[index, 0] := toggleIt; eventKind[index, 1] := amount; {object# linked to} end; guitar: begin eventKind[index, 0] := playIt; eventKind[index, 1] := 0; end; upStar: begin eventKind[index, 0] := ascendIt; eventKind[index, 1] := amount; {room # linked to} end; dnStar: begin eventKind[index, 0] := descendIt; eventKind[index, 1] := amount; {room # linked to} end; otherwise eventKind[index, 0] := ignoreIt; end; {case} end; end; {=================================} procedure ReadyRoom; var index: Integer; begin with testRoom do begin rightIsOpen := rightOpen; leftIsOpen := leftOpen; end; ExtractEventRects; end; {=================================} function RectLap (rect1, rect2: Rect): Boolean; var dumRect: Rect; begin RectLap := FALSE; if (rect1.right < rect2.left) then Exit(RectLap); if (rect2.right < rect2.left) then Exit(RectLap); if (rect1.bottom < rect2.top) then Exit(RectLap); if (rect2.bottom < rect2.top) then Exit(RectLap); RectLap := SectRect(rect1, rect2, dumRect); end; {=================================} procedure Collision (whatKind, who: Integer); var tempInt: Integer; tempRect, srcR: Rect; begin case (whatKind) of ignoreIt: ; crashIt: begin SysBeep(1); lifeNormal := FALSE; with theGlider do begin mode := fadingOut; destRect.top := destRect.bottom - 20; if (isForward) then srcNum := 0 else srcNum := 2; end; end; liftIt: if (not airOut) then liftAmount := -7; moveIt: begin SysBeep(1); lifeNormal := FALSE; with theGlider do begin mode := fadingOut; destRect.top := destRect.bottom - 20; if (isForward) then srcNum := 0 else srcNum := 2; end; end; dropIt: if (not airOut) then liftAmount := 7; turnItLeft: begin shiftAmount := -7; if (lifeNormal) then with theGlider do if (isRight) then begin lifeNormal := FALSE; theGlider.mode := turnRt2Lf; end; end; turnItRight: begin shiftAmount := 7; if (lifeNormal) then with theGlider do if (not isRight) then begin lifeNormal := FALSE; theGlider.mode := turnLf2Rt; end; end; burnIt: begin liftAmount := -7; if ((lifeNormal) and (theGlider.destRect.bottom > eventKind[who, 1])) then with theGlider do begin SysBeep(1); lifeNormal := FALSE; if (isRight) then phase := 1; mode := burning; destRect.top := destRect.bottom - 36; end; end; awardIt: if (eventKind[who, 1] <> 0) then begin SysBeep(1); eventKind[who, 1] := 0; end; extraIt: if (eventKind[who, 1] <> 0) then begin SysBeep(1); eventKind[who, 1] := 0; end; spillIt: {grease upright} begin eventRect[who].left := eventRect[who].right; eventRect[who].right := eventRect[who].right; eventRect[who].top := eventRect[who].bottom - 5; eventKind[who, 0] := ignoreIt; {signal to the cycleOb loop that a spill has occurred} thisHouse.theRooms[roomAt].theObjects[who].isOn := FALSE; end; slideIt: {grease spilt} begin with theGlider do begin tempInt := eventRect[who].top - touchRect.bottom + 1; destRect.top := destRect.top + tempInt; destRect.bottom := destRect.bottom + tempInt; touchRect.top := touchRect.top + tempInt; touchRect.bottom := touchRect.bottom + tempInt; end; sliding := TRUE; end; bandIt: if (eventKind[who, 1] <> 0) then begin SysBeep(1); eventKind[who, 1] := 0; end; energizeIt: if (eventKind[who, 1] <> 0) then begin SysBeep(1); theGlider.energy := theGlider.energy + eventKind[who, 1]; eventKind[who, 1] := 0; end; trickIt: if (eventKind[who, 1] <> 0) then begin SysBeep(1); eventKind[who, 1] := 0; end; lightIt: if (lightsOut) then begin SysBeep(1); testRoom.conditionCode := 0; lightsOut := FALSE; end; airOnIt: if (airOut) then begin SysBeep(1); airOut := FALSE; end; zapIt: begin if (eventKind[who, 1] <> 0) then begin lifeNormal := FALSE; with theGlider do begin mode := fadingOut; destRect.top := destRect.bottom - 20; if (isForward) then srcNum := 0 else srcNum := 2; end; {end - with theGlider} end; {end - if (eventKind} end; {end - zapIt} toggleIt: if (eventKind[who, 2] < TickCount) then begin SysBeep(1); tempInt := eventKind[who, 1]; with thisHouse.theRooms[roomAt].theObjects[tempInt] do begin isOn := not isOn; case objectIs of lftFan: if (eventKind[tempInt, 0] = ignoreIt) then begin SysBeep(1); eventKind[tempInt, 0] := turnItLeft; end else eventKind[tempInt, 0] := ignoreIt; ritFan: if (eventKind[tempInt, 0] = ignoreIt) then begin SysBeep(1); eventKind[tempInt, 0] := turnItRight; end else eventKind[tempInt, 0] := ignoreIt; shredr: if (eventKind[tempInt, 0] = ignoreIt) then eventKind[tempInt, 0] := shredIt else eventKind[tempInt, 0] := ignoreIt; otherwise end; {case} end; {with} eventKind[who, 2] := TickCount + 90; end; playIt: if (eventKind[who, 1] < TickCount) then begin SysBeep(1); eventKind[who, 1] := TickCount + 120; end; ascendIt: begin lifeNormal := FALSE; theGlider.mode := ascending; playing := FALSE; end; descendIt: begin lifeNormal := FALSE; theGlider.mode := descending; playing := FALSE; end; shredIt: begin lifeNormal := FALSE; with theGlider do begin mode := shredding; destRect.top := eventRect[who].bottom; destRect.bottom := destRect.top; destRect.left := eventRect[who].left + 12; destRect.right := destRect.left + 48; shadoDest.left := destRect.left; shadoDest.right := destRect.right; phase := 0; end; end; steamIt: begin liftAmount := -7; shiftAmount := -7; end; otherwise end; {case} end; {=================================} procedure SearchRects; var index, outside: Integer; hotRect, tempRect: Rect; {----------------} procedure BiteIt; begin with theGlider do begin SysBeep(1); lifeNormal := FALSE; mode := fadingOut; if (isForward) then srcNum := 0 else srcNum := 2; end; end; {----------------} procedure GetItLegal; begin {do a bump sound here} with theGlider do begin with destRect do begin left := left + outside; right := right + outside; end; with shadoDest do begin left := left + outside; right := right + outside; end; with touchRect do begin left := left + outside; right := right + outside; end; end; end; {----------------} begin with theGlider do begin hotRect := touchRect; {get 'hot rect'} if (rightIsOpen) then {check right edge} begin if (destRect.left > 500) then begin playing := FALSE; Exit(SearchRects); end end else if (destRect.right > 512) then begin outside := 512 - destRect.right; GetItLegal; end; if (leftIsOpen) then {check left edge} begin if (destRect.right < 12) then begin playing := FALSE; Exit(SearchRects); end; end else if (destRect.left < 0) then begin outside := -destRect.left; GetItLegal; end; if (destRect.bottom > floorLimit) then {check floor} BiteIt; end; {---with theGlider do---} shiftAmount := 0; for index := 1 to nObjects do if (RectLap(eventRect[index], hotRect)) then Collision(eventKind[index, 0], index); end; {=================================} procedure GetInput; var pull: Integer; thePt: Point; dest: Rect; {--------------------} procedure PushIt (howFast: Integer); begin with theGlider do forVel := howFast; end; {--------------------} procedure FireBand; begin end; {--------------------} begin with theGlider do begin case controlMethod of holdKey: begin GetKeys(theKeys); if (theKeys[leftKey]) then if (isRight) then begin isForward := FALSE; srcNum := 1; forVel := -maxThrust; end else begin isForward := TRUE; srcNum := 2; forVel := -maxThrust; end else if (theKeys[rightKey]) then if (isRight) then begin isForward := TRUE; srcNum := 0; forVel := maxThrust; end else begin isForward := FALSE; srcNum := 3; forVel := maxThrust; end else {no key of import down} begin if (isRight) then begin isForward := TRUE; srcNum := 0; forVel := 0; end else begin isForward := TRUE; srcNum := 2; forVel := 0; end; end; if (theKeys[bandKey] and (not bandBorne)) then {fire rubber bands} FireBand; if (theKeys[energyKey]) then begin if (((isRight) and (isForward)) or ((not isRight) and (not isForward))) then PushIt(16) else PushIt(-16); end; end; dropKey: begin if (((isRight) and (isForward)) or ((not isRight) and (not isForward))) then forVel := maxThrust else forVel := -maxThrust; GetKeys(theKeys); if (theKeys[leftKey]) then if (isRight) then begin isForward := FALSE; srcNum := 1; forVel := -maxThrust; end else begin isForward := TRUE; srcNum := 2; forVel := -maxThrust; end else if (theKeys[rightKey]) then if (isRight) then begin isForward := TRUE; srcNum := 0; forVel := maxThrust; end else begin isForward := FALSE; srcNum := 3; forVel := maxThrust; end; if (theKeys[bandKey] and (not bandBorne)) then {fire rubber bands} FireBand; if (theKeys[energyKey]) then begin if (((isRight) and (isForward)) or ((not isRight) and (not isForward))) then PushIt(16) else PushIt(-16); end; end; {end - dropKey} absMouse: begin GetKeys(theKeys); if ((theKeys[bandKey]) and (not bandBorne)) then FireBand; GetMouse(thePt); pull := (thePt.h - 256 + rightOffset) div 32; if (pull > maxThrust) then pull := maxThrust else if (pull < -maxThrust) then pull := -maxThrust; forVel := pull; if (isRight) then if (forVel < 0) then begin isForward := FALSE; srcNum := 1; if (theKeys[energyKey]) then PushIt(-16); if (button) then begin if (not buttonFires) then PushIt(-16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin isForward := TRUE; srcNum := 0; if (theKeys[energyKey]) then PushIt(16); if (button) then begin if (not buttonFires) then PushIt(16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin if (forVel < 0) then begin isForward := TRUE; srcNum := 2; if (theKeys[energyKey]) then PushIt(-16); if (button) then begin if (not buttonFires) then PushIt(-16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin isForward := FALSE; srcNum := 3; if (theKeys[energyKey]) then PushIt(16); if (button) then begin if (not buttonFires) then PushIt(16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end; end; end; {end - absMouse} relMouse: begin GetKeys(theKeys); if (theKeys[bandKey] and (not bandBorne)) then {fire rubber bands} FireBand; GetMouse(thePt); forVel := (thePt.h - 256 + rightOffset) div mouseSlop; if (forVel > maxThrust) then forVel := maxThrust else if (forVel < -maxThrust) then forVel := -maxThrust; CenterMouse; if (isRight) then if (forVel < 0) then begin isForward := FALSE; srcNum := 1; if (theKeys[energyKey]) then PushIt(-16); if (button) then begin if (not buttonFires) then PushIt(-16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin isForward := TRUE; srcNum := 0; if (theKeys[energyKey]) then PushIt(16); if (button) then begin if (not buttonFires) then PushIt(16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin if (forVel < 0) then begin isForward := TRUE; srcNum := 2; if (theKeys[energyKey]) then PushIt(-16); if (button) then begin if (not buttonFires) then PushIt(-16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end else begin isForward := FALSE; srcNum := 3; if (theKeys[energyKey]) then PushIt(16); if (button) then begin if (not buttonFires) then PushIt(16) else if ((not bandBorne) and (buttonFires)) then FireBand; end; end; end; end; {end - relMouse} otherwise ; end; {case} end; {with theGlider} end; {=================================} procedure MoveGlider; begin with theGlider do begin liftAmount := liftAmount + 1; {add gravity} if (sliding) then begin liftAmount := 0; {zero out lift} sliding := FALSE; end else begin {vertical offset of glider} destRect.top := destRect.top + liftAmount; destRect.bottom := destRect.bottom + liftAmount; touchRect.top := touchRect.top + liftAmount; touchRect.bottom := touchRect.bottom + liftAmount; end; forVel := forVel + shiftAmount; {horizontal offset of glider} destRect.left := destRect.left + forVel; destRect.right := destRect.right + forVel; touchRect.left := destRect.left + 10; {touch rect is inset from dest} touchRect.right := destRect.right - 10; shadoDest.left := destRect.left; {shadow has same l. & r. as dest} shadoDest.right := destRect.right; end; end; {=================================} procedure IncInt (var i: integer); inline $205F, {MOVEA.W (A7)+, A0 } $5250; {ADDQ.W #$1, (A0) } {=================================} procedure IncLong (var l: longint); inline $205F, {MOVEA.L (A7)+, A0 } $5290; {ADDQ.L #$1, (A0) } {=================================} procedure MoveCycleObs; var index, diff: Integer; begin for index := 1 to nCycleObs do with cycleObjects[index] do case kindIs of candle: begin IncLong(position); if (position > 50) then position := 48; end; grease: begin if (eventKind[tiedTo, 0] = ignoreIt) then begin SysBeep(1); eventKind[tiedTo, 0] := slideIt; reset := 1; end; if ((reset <> 0) and (reset <> 999)) then begin reset := reset + 1; if (reset > 4) then begin velocity := velocity + 1; eventRect[tiedTo].right := eventRect[tiedTo].right + 1; if (velocity > position) then reset := 999; end else begin if (reset < 3) then accel := 58 else accel := 59; end; end; end; outlet: begin if (accel = 25) then begin if (TickCount > (position + reset)) then begin accel := binaryFlip + 51; position := TickCount; eventKind[tiedTo, 1] := 1; end; end else begin if (TickCount > (position + 60)) then begin accel := 25; position := TickCount; eventKind[tiedTo, 1] := 0; end else accel := binaryFlip + 51; end; end; drip: begin if (phase < 57) then begin if (binaryFlip <> 0) then begin IncInt(phase); if (phase = 57) then position := position + 160; end; end else begin velocity := velocity + accel; position := position + velocity; if (position > reset) then begin velocity := 0; position := holdRect.bottom * 32; if (inColor) then begin CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, eventRect[tiedTo], eventRect[tiedTo], srcCopy, wholeRgn); CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, eventRect[tiedTo], eventRect[tiedTo], srcCopy, wholeRgn); end else begin CopyBits(offVirginMap, offLoadMap, eventRect[tiedTo], eventRect[tiedTo], srcCopy, wholeRgn); CopyBits(offVirginMap, mainWndo^.portBits, eventRect[tiedTo], eventRect[tiedTo], srcCopy, wholeRgn); end; eventRect[tiedTo] := holdRect; phase := 53; end; wholeRect := eventRect[tiedTo]; with eventRect[tiedTo] do begin diff := (position div 32) - bottom; bottom := bottom + diff; top := top + diff; end; wholeRect.bottom := wholeRect.bottom + diff end; {else } end; {drip} toastr: if (phase <> 0) then begin if (binaryFlip = 0) then begin phase := phase + 1; if (phase > 65) then phase := 60; end; velocity := velocity + accel; position := position + velocity; if (position > reset) then begin velocity := -velocity; position := reset; reset := TickCount + thisHouse.theRooms[roomAt].theObjects[tiedTo].extra; phase := 0; end; wholeRect := eventRect[tiedTo]; with eventRect[tiedTo] do begin diff := (position div 32) - bottom; bottom := bottom + diff; top := top + diff; end; if (diff > 0) then wholeRect.bottom := wholeRect.bottom + diff else wholeRect.top := wholeRect.top + diff; end else begin if (TickCount > reset) then begin reset := position; phase := 60; end; end; {toastr} ball: begin velocity := velocity + accel; position := position + velocity; if (position > reset) then begin velocity := -velocity; position := reset; end; wholeRect := eventRect[tiedTo]; with eventRect[tiedTo] do begin diff := (position div 32) - bottom; bottom := bottom + diff; top := top + diff; end; if (diff > 0) then wholeRect.bottom := wholeRect.bottom + diff else wholeRect.top := wholeRect.top + diff; end; {ball} fshBwl: if (phase <> 0) then begin if ((velocity > -16) and (velocity < 16)) then phase := 69 else begin if (velocity < 0) then phase := 66 else phase := 68; end; velocity := velocity + accel; position := position + velocity; if (position > reset) then begin velocity := -velocity; position := reset; reset := TickCount + thisHouse.theRooms[roomAt].theObjects[tiedTo].extra; phase := 0; end; wholeRect := eventRect[tiedTo]; with eventRect[tiedTo] do begin diff := (position div 32) - bottom; bottom := bottom + diff; top := top + diff; end; if (diff > 0) then wholeRect.bottom := wholeRect.bottom + diff else wholeRect.top := wholeRect.top + diff; end else begin if (TickCount > reset) then begin reset := position; phase := 66; end; end; {fish bowl} teaKtl: begin if (TickCount > reset) then begin eventKind[tiedTo, 0] := steamIt; if (phase = 0) then ; phase := phase + 1; if (phase > 10) then begin phase := 0; eventKind[tiedTo, 0] := ignoreIt; reset := TickCount + position; end; end; end; otherwise end; {case / with / index} end; {=================================} procedure DoSpecial; begin with theGlider do case mode of fadingIn: begin IncInt(phase); if (phase > 16) then begin if (isForward) then srcNum := 0 else srcNum := 3; lifeNormal := TRUE; phase := 0; mode := normal; end end; fadingOut: begin IncInt(phase); if (isRight) then srcNum := 0 else srcNum := 2; if (phase > 16) then playing := FALSE; end; turnRt2Lf: begin IncInt(phase); if (phase > 11) then begin lifeNormal := TRUE; phase := 0; mode := normal; shiftAmount := 0; isRight := FALSE; end; SearchRects; destRect.left := destRect.left + shiftAmount; destRect.right := destRect.right + shiftAmount; touchRect.left := touchRect.left + shiftAmount; touchRect.right := touchRect.right + shiftAmount; shadoDest.left := shadoDest.left + shiftAmount; shadoDest.right := shadoDest.right + shiftAmount; end; turnLf2Rt: begin IncInt(phase); if (phase > 11) then begin lifeNormal := TRUE; phase := 0; mode := normal; shiftAmount := 0; isRight := TRUE; end; SearchRects; destRect.left := destRect.left + shiftAmount; destRect.right := destRect.right + shiftAmount; touchRect.left := touchRect.left + shiftAmount; touchRect.right := touchRect.right + shiftAmount; shadoDest.left := shadoDest.left + shiftAmount; shadoDest.right := shadoDest.right + shiftAmount; end; burning: begin phase := 1 - phase; if (isRight) then begin srcNum := 24 + phase; forVel := 1; end else begin srcNum := 26 + phase; forVel := -1; end; SearchRects; MoveGlider; end; ascending: begin destRect.left := destRect.left - 2; destRect.right := destRect.left + 48; destRect.top := destRect.top - 6; destRect.bottom := destRect.top + 20; shadoDest.left := destRect.left; shadoDest.right := destRect.right; touchRect := destRect; InsetRect(touchRect, 10, 5); if (destRect.top < 150) then begin lifeNormal := TRUE; phase := 0; mode := normal; end; end; descending: begin destRect.left := destRect.left + 2; destRect.right := destRect.left + 48; destRect.top := destRect.top + 6; destRect.bottom := destRect.top + 20; shadoDest.left := destRect.left; shadoDest.right := destRect.right; touchRect := destRect; InsetRect(touchRect, 10, 5); if (destRect.top > 150) then begin lifeNormal := TRUE; phase := 0; mode := normal; end; end; shredding: begin if (phase = 0) then begin destRect.bottom := destRect.bottom + 1; if (destRect.bottom >= destRect.top + 36) then phase := 1; end else begin destRect.top := destRect.top + 8; destRect.bottom := destRect.bottom + 8; if (destRect.top > 342) then begin phase := 0; playing := FALSE; end; end; end; {end - shred} otherwise ; end; end; {=================================} procedure DrawScene; var index, tempInt: Integer; tempRect, tempSmRect: Rect; begin if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do CopyBits(offVirginMap, offLoadMap, wholeRect, wholeRect, srcCopy, wholeRgn); {-----pop masks on-----} if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do begin case kindIs of candle: CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[position], srcRect[position], wholeRect); outlet: CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[accel], srcRect[accel], wholeRect); ball: CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[kindIs], srcRect[kindIs], eventRect[tiedTo]); drip: CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[phase], srcRect[phase], eventRect[tiedTo]); toastr: if (phase <> 0) then begin SetPort(offLoadPort); HLock(Handle(toastRgn)); SetClip(toastRgn); CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[phase], srcRect[phase], eventRect[tiedTo]); ClipRect(wholeArea); HUnlock(Handle(toastRgn)); SetPort(mainWndo); end; fshBwl: if (phase <> 0) then CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[phase], srcRect[phase], eventRect[tiedTo]) else CopyMask(offPlayerMap, offMaskMap, offLoadMap, srcRect[69], srcRect[69], eventRect[tiedTo]); otherwise ; end; {case} oldRect := wholeRect; end; {-----pop to visible screen-----} if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do CopyBits(offLoadMap, mainWndo^.portBits, wholeRect, wholeRect, srcCopy, wholeRgn); with theGlider do begin if (isRight) then CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, shadoRct[0], shadoRct[0], shadoDest) else CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, shadoRct[1], shadoRct[1], shadoDest); if (lifeNormal) then CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, glideRct[srcNum], glideRct[srcNum], destRect) else case mode of fadingIn, fadingOut: begin tempInt := nextPhase[mode, phase]; if (not isRight) then tempInt := tempInt + 7; CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, glideRct[srcNum], glideRct[tempInt], destRect); end; turnLf2Rt, turnRt2Lf: begin tempInt := nextPhase[mode, phase]; CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, glideRct[tempInt], glideRct[tempInt], destRect); end; burning, ascending, descending: CopyMask(offPlayerMap, offMaskMap, mainWndo^.portBits, glideRct[srcNum], glideRct[srcNum], destRect); otherwise ; end; {case} end; end; {=================================} procedure DrawCScene; var index, tempInt: Integer; tempRect, tempSmRect: Rect; begin if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do CopyBits(BitMapPtr(virginCPtr^.portPixMap^)^, BitMapPtr(loadCPtr^.portPixMap^)^, oldRect, oldRect, srcCopy, wholeRgn); {-----pop masks on-----} if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do begin case kindIs of candle: CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[position], srcRect[position], wholeRect); outlet, grease: CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[accel], srcRect[accel], wholeRect); ball: CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[kindIs], srcRect[kindIs], eventRect[tiedTo]); drip: CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[phase], srcRect[phase], eventRect[tiedTo]); toastr: if (phase <> 0) then begin SetPort(GrafPtr(loadCPtr)); HLock(Handle(toastRgn)); SetClip(toastRgn); CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[phase], srcRect[phase], eventRect[tiedTo]); HUnlock(Handle(toastRgn)); ClipRect(wholeArea); SetPort(GrafPtr(mainWndo)); end; fshBwl: begin if (phase <> 0) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[phase], srcRect[phase], eventRect[tiedTo]) else CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, BitMapPtr(loadCPtr^.portPixMap^)^, srcRect[69], srcRect[69], eventRect[tiedTo]); end; otherwise end; {case} oldRect := wholeRect; end; {-----pop to visible screen-----} if (nCycleObs > 0) then for index := 1 to nCycleObs do with cycleObjects[index] do begin if (kindIs <> grease) then CopyBits(BitMapPtr(loadCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wholeRect, wholeRect, srcCopy, wholeRgn) else begin CopyBits(BitMapPtr(loadCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wholeRect, wholeRect, srcCopy, wholeRgn); SetPort(GrafPtr(mainWndo)); PenNormal; PenSize(2, 2); MoveTo(wholeRect.right, wholeRect.bottom - 2); LineTo(velocity, wholeRect.bottom - 2); end; end; with theGlider do begin if (lifeNormal) then CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, glideRct[srcNum], glideRct[srcNum], destRect) else case mode of fadingIn, fadingOut: begin tempInt := nextPhase[mode, phase]; if (not isRight) then tempInt := tempInt + 7; CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, glideRct[srcNum], glideRct[tempInt], destRect); end; turnLf2Rt, turnRt2Lf: begin tempInt := nextPhase[mode, phase]; CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, glideRct[tempInt], glideRct[tempInt], destRect); end; burning, ascending, descending: CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, glideRct[srcNum], glideRct[srcNum], destRect); shredding: begin SetRect(tempRect, 265, 208 - (destRect.bottom - destRect.top), 313, 208); CopyMask(BitMapPtr(objectCPtr^.portPixMap^)^, offMaskMap, GrafPtr(mainWndo)^.portBits, tempRect, tempRect, destRect); end; otherwise ; end; {case} end; end; {=================================} procedure FlyGlider; var i: Integer; profileTime: LongInt; tempRect: Rect; begin AutoHideShow(TRUE); thisHouse.theRooms[roomAt] := thisRoom; testRoom := thisRoom; if (inColor) then CopyBits(BitMapPtr(loadCPtr^.portPixMap^)^, GrafPtr(mainWndo)^.portBits, wholeArea, wholeArea, srcCopy, GrafPtr(mainWndo)^.visRgn) else CopyBits(offLoadMap, mainWndo^.portBits, wholeArea, wholeArea, srcCopy, mainWndo^.visRgn); SetPort(GrafPtr(mainWndo)); PenNormal; TextFont(0); TextSize(12); TextMode(patOr); ClipRect(fullArea); SetRect(tempRect, -rightOffset, -downOffset, 512 + (2 * rightOffset), 0); FillRect(tempRect, black); SetRect(tempRect, -rightOffset, 342, 512 + (2 * rightOffset), 342 + downOffset); FillRect(tempRect, black); SetRect(tempRect, -rightOffset, 0, 0, 342); FillRect(tempRect, black); SetRect(tempRect, 512, 0, 512 + rightOffset, 342); FillRect(tempRect, black); ClipRect(wholeArea); playing := TRUE; pausing := FALSE; hasToast := FALSE; sliding := FALSE; ReadyRoom; ReadyGlider; HideCursor; while ((playing) and (not pausing)) do begin timeIs := TickCount; liftAmount := 2; binaryFlip := BitXOr(binaryFlip, 1); if (lifeNormal) then begin SearchRects; GetInput; MoveGlider; end else DoSpecial; if (playing) then begin if (nCycleObs > 0) then MoveCycleObs; SetPort(GrafPtr(mainWndo)); if (inColor) then DrawCScene else DrawScene; end; if (theKeys[kTabKeyMap]) then {pausing} begin repeat GetKeys(theKeys); until (not theKeys[kTabKeyMap]); repeat GetKeys(theKeys); until (theKeys[kTabKeyMap]); repeat GetKeys(theKeys); until (not theKeys[kTabKeyMap]); end; if (theKeys[kCommandKeyMap]) then {aborted} begin playing := FALSE; end; repeat until (TickCount >= (timeIs + 2)); end; if (hasToast) then begin hasToast := FALSE; DisposeRgn(toastRgn); end; lightsOut := FALSE; airOut := FALSE; LoadABackground(thisRoom.backPictID); DrawAllObjects; SetPort(GrafPtr(mainWndo)); PenNormal; TextFont(0); TextSize(12); TextMode(patOr); ClipRect(fullArea); SetRect(tempRect, -rightOffset, -downOffset, 512 + (2 * rightOffset), 0); FillRect(tempRect, black); SetRect(tempRect, -rightOffset, 342, 512 + (2 * rightOffset), 342 + downOffset); FillRect(tempRect, black); SetRect(tempRect, -rightOffset, 0, 0, 342); FillRect(tempRect, black); SetRect(tempRect, 512, 0, 512 + rightOffset, 342); FillRect(tempRect, black); ClipRect(wholeArea); FlushEvents(everyEvent, 0); InitCursor; AutoHideShow(FALSE); end; {=================================} end.