//============================================================================ //---------------------------------------------------------------------------- // Dynamics3.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kBalloonStart 310 #define kCopterStart 8 #define kDartVelocity 6 dynaPtr dinahs; short numDynamics; extern Rect breadSrc[]; extern short numLights; extern Boolean evenFrame; //============================================================== Functions //-------------------------------------------------------------- HandleDynamics // This is the master function that calls all the specific handlers above. void HandleDynamics (void) { short i; for (i = 0; i < numDynamics; i++) { switch (dinahs[i].type) { case kSparkle: HandleSparkleObject(i); break; case kToaster: HandleToast(i); break; case kMacPlus: HandleMacPlus(i); break; case kTV: HandleTV(i); break; case kCoffee: HandleCoffee(i); break; case kOutlet: HandleOutlet(i); break; case kVCR: HandleVCR(i); break; case kStereo: HandleStereo(i); break; case kMicrowave: HandleMicrowave(i); break; case kBalloon: HandleBalloon(i); break; case kCopterLf: case kCopterRt: HandleCopter(i); break; case kDartLf: case kDartRt: HandleDart(i); break; case kBall: HandleBall(i); break; case kDrip: HandleDrip(i); break; case kFish: HandleFish(i); break; default: break; } } } //-------------------------------------------------------------- HandleDynamics // This is the master function that calls all the various rendering handlersÉ // above. void RenderDynamics (void) { short i; for (i = 0; i < numDynamics; i++) { switch (dinahs[i].type) { case kToaster: RenderToast(i); break; case kBalloon: RenderBalloon(i); break; case kCopterLf: case kCopterRt: RenderCopter(i); break; case kDartLf: case kDartRt: RenderDart(i); break; case kBall: RenderBall(i); break; case kDrip: RenderDrip(i); break; case kFish: RenderFish(i); break; default: break; } } } //-------------------------------------------------------------- ZeroDinah void ZeroDinah(dynaType &dinah) { dinah.type = kObjectIsEmpty; QSetRect(&dinah.dest, 0, 0, 0, 0); QSetRect(&dinah.whole, 0, 0, 0, 0); dinah.hVel = 0; dinah.vVel = 0; dinah.count = 0; dinah.frame = 0; dinah.timer = 0; dinah.position = 0; dinah.room = 0; dinah.byte0 = 0; dinah.active = false; } //-------------------------------------------------------------- ZeroDinahsNotInRoom void ZeroDinahsNotInRoom (SInt16 room) { short i; short newNumDynamics = 0; for (i = 0; i < numDynamics; i++) { dynaType &dinah = dinahs[i]; if (dinah.room == room) { if (newNumDynamics != numDynamics) memcpy(&dinahs[newNumDynamics], &dinahs[i], sizeof(dynaType)); newNumDynamics++; } } for (i = newNumDynamics; i < kMaxDynamicObs; i++) ZeroDinah(dinahs[i]); numDynamics = newNumDynamics; } //-------------------------------------------------------------- ZeroDinahs // This clears all dynamics - zeros them all out. Used to initialize them. void ZeroDinahs (void) { short i; for (i = 0; i < kMaxDynamicObs; i++) ZeroDinah(dinahs[i]); numDynamics = 0; } //-------------------------------------------------------------- AddDynamicObject // When a room is being drawn, various dynamic objects are pointed here. // This function sets up the structures to handle them. short AddDynamicObject (short what, Rect *where, objectType *who, short room, short index, Boolean isOn, Boolean keepExisting) { short position, velocity; Boolean lilFrame; short dynIndex = -1; if (!keepExisting) { if (numDynamics >= kMaxDynamicObs) return (-1); dynIndex = numDynamics; numDynamics++; dinahs[dynIndex].type = what; } else { for (int i = 0; i < numDynamics; i++) { if (dinahs[i].type == what && dinahs[i].room == room && dinahs[i].byte0 == index) { dynIndex = i; break; } } if (dynIndex == -1) return (-1); } switch (what) { case kSparkle: dinahs[dynIndex].dest = sparkleSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left, where->top); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = RandomInt(60) + 15; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kToaster: { short baselineDelta = 0; if (keepExisting) baselineDelta = dinahs[dynIndex].dest.top - (where->top - 2); dinahs[dynIndex].dest = breadSrc[0]; CenterRectInRect(&dinahs[dynIndex].dest, where); VOffsetRect(&dinahs[dynIndex].dest, where->top - dinahs[dynIndex].dest.top + baselineDelta); dinahs[dynIndex].whole = dinahs[dynIndex].dest; dinahs[dynIndex].hVel = where->top + 2; // hVel used as clip if (!keepExisting) { position = who->data.g.height; // reverse engineer init. vel. velocity = 0; do { velocity++; position -= velocity; } while (position > 0); dinahs[dynIndex].vVel = -velocity; dinahs[dynIndex].count = velocity; // count = initial velocity dinahs[dynIndex].frame = (short)who->data.g.delay * 3; dinahs[dynIndex].timer = dinahs[dynIndex].frame; dinahs[dynIndex].position = 0; // launch/idle state dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } } break; case kMacPlus: dinahs[dynIndex].dest = plusScreen1; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 10, where->top + playOriginV + 7); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kTV: dinahs[dynIndex].dest = tvScreen1; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 17, where->top + playOriginV + 10); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kCoffee: dinahs[dynIndex].dest = coffeeLight1; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 32, where->top + playOriginV + 57); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; if (isOn) dinahs[dynIndex].timer = 200; else dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kOutlet: dinahs[dynIndex].dest = outletSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH, where->top + playOriginV); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = numLights; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = ((short)who->data.g.delay * 6) / kTicksPerFrame; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = dinahs[dynIndex].count; dinahs[dynIndex].position = 0; // launch/idle state dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kVCR: dinahs[dynIndex].dest = vcrTime1; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 64, where->top + playOriginV + 6); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; if (isOn) dinahs[dynIndex].timer = 115; else dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kStereo: dinahs[dynIndex].dest = stereoLight1; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 56, where->top + playOriginV + 20); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kMicrowave: dinahs[dynIndex].dest = microOn; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left + playOriginH + 14, where->top + playOriginV + 13); dinahs[dynIndex].dest.right = dinahs[dynIndex].dest.left + 48; dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = 0; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = 0; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } break; case kBalloon: { short baselineDelta = 0; if (keepExisting) baselineDelta = dinahs[dynIndex].dest.bottom - kBalloonStart; dinahs[dynIndex].dest = balloonSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left, 0); dinahs[dynIndex].dest.bottom = kBalloonStart + baselineDelta; dinahs[dynIndex].dest.top = dinahs[dynIndex].dest.bottom - RectTall(&balloonSrc[0]); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = 0; dinahs[dynIndex].vVel = -2; dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = dinahs[dynIndex].count; dinahs[dynIndex].position = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; // initially idle } } break; case kCopterLf: case kCopterRt: { short baselineDeltaH = 0; short baselineDeltaV = 0; if (keepExisting) { baselineDeltaH = dinahs[dynIndex].dest.left - dinahs[dynIndex].position; baselineDeltaV = dinahs[dynIndex].dest.top - kCopterStart; } dinahs[dynIndex].dest = copterSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left, 0); dinahs[dynIndex].dest.top = kCopterStart + baselineDeltaV; dinahs[dynIndex].dest.bottom = dinahs[dynIndex].dest.top + RectTall(&copterSrc[0]); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].position = dinahs[dynIndex].dest.left; if (what == kCopterLf) dinahs[dynIndex].hVel = -1; else dinahs[dynIndex].hVel = 1; dinahs[dynIndex].vVel = 2; dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = dinahs[dynIndex].count; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; // initially idle } } break; case kDartLf: case kDartRt: dinahs[dynIndex].dest = dartSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); if (what == kDartLf) { QOffsetRect(&dinahs[dynIndex].dest, kRoomWide - RectWide(&dartSrc[0]), where->top); dinahs[dynIndex].hVel = -kDartVelocity; dinahs[dynIndex].frame = 0; } else { QOffsetRect(&dinahs[dynIndex].dest, 0, where->top); dinahs[dynIndex].hVel = kDartVelocity; dinahs[dynIndex].frame = 2; } dinahs[dynIndex].whole = dinahs[dynIndex].dest; dinahs[dynIndex].position = dinahs[dynIndex].dest.top; if (!keepExisting) { dinahs[dynIndex].vVel = 2; dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[dynIndex].timer = dinahs[dynIndex].count; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; // initially idle } break; case kBall: { short baselineDelta = 0; if (keepExisting) baselineDelta = dinahs[dynIndex].dest.bottom - dinahs[dynIndex].position; dinahs[dynIndex].dest = ballSrc[0]; ZeroRectCorner(&dinahs[dynIndex].dest); QOffsetRect(&dinahs[dynIndex].dest, where->left, where->top + baselineDelta); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].position = dinahs[dynIndex].dest.bottom; dinahs[dynIndex].hVel = 0; position = who->data.h.length; // reverse engineer init. vel. velocity = 0; evenFrame = true; lilFrame = true; do { if (lilFrame) velocity++; lilFrame = !lilFrame; position -= velocity; } while (position > 0); dinahs[dynIndex].vVel = -velocity; dinahs[dynIndex].moving = false; dinahs[dynIndex].count = -velocity; // count = initial velocity dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = 0; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].active = isOn; } } break; case kDrip: { short baselineDelta = 0; if (keepExisting) baselineDelta = dinahs[dynIndex].dest.top - dinahs[dynIndex].hVel; dinahs[dynIndex].dest = dripSrc[0]; CenterRectInRect(&dinahs[dynIndex].dest, where); VOffsetRect(&dinahs[dynIndex].dest, where->top - dinahs[dynIndex].dest.top + baselineDelta); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].hVel = dinahs[dynIndex].dest.top; // remember dinahs[dynIndex].position = dinahs[dynIndex].dest.top + who->data.h.length; dinahs[dynIndex].vVel = 0; dinahs[dynIndex].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[dynIndex].frame = 3; dinahs[dynIndex].timer = dinahs[dynIndex].count; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } } break; case kFish: { short baselineDelta = 0; if (keepExisting) baselineDelta = dinahs[dynIndex].dest.bottom - dinahs[dynIndex].position; dinahs[dynIndex].dest = fishSrc[0]; QOffsetRect(&dinahs[dynIndex].dest, where->left + 10, where->top + 8 + baselineDelta); dinahs[dynIndex].whole = dinahs[dynIndex].dest; if (!keepExisting) { dinahs[dynIndex].position = dinahs[dynIndex].dest.bottom; dinahs[dynIndex].hVel = ((short)who->data.h.delay * 6) / kTicksPerFrame; position = who->data.g.height; // reverse engineer init. vel. velocity = 0; evenFrame = true; lilFrame = true; do { if (lilFrame) velocity++; lilFrame = !lilFrame; position -= velocity; } while (position > 0); dinahs[dynIndex].vVel = -velocity; dinahs[dynIndex].count = -velocity; // count = initial velocity dinahs[dynIndex].frame = 0; dinahs[dynIndex].timer = dinahs[dynIndex].hVel; dinahs[dynIndex].room = room; dinahs[dynIndex].byte0 = (Byte)index; dinahs[dynIndex].byte1 = 0; dinahs[dynIndex].moving = false; dinahs[dynIndex].active = isOn; } } break; default: break; } return dynIndex; }