//cycle the flashing light for when mine destroyed void FlashFrame (void) { static fixang flash_ang = 0; if (!(gameData.reactor.bDestroyed || gameStates.gameplay.seismic.nMagnitude)) { gameStates.render.nFlashScale = I2X (1); return; } if (gameStates.app.bEndLevelSequence) return; if (paletteManager.BlueEffect () > 10) //whiting out return; // flash_ang += FixMul(FLASH_CYCLE_RATE, gameData.time.xFrame); if (gameStates.gameplay.seismic.nMagnitude) { fix xAddedFlash = abs(gameStates.gameplay.seismic.nMagnitude); if (xAddedFlash < I2X (1)) xAddedFlash *= 16; flash_ang += (fixang) FixMul (gameStates.render.nFlashRate, FixMul(gameData.time.xFrame, xAddedFlash+I2X (1))); FixFastSinCos (flash_ang, &gameStates.render.nFlashScale, NULL); gameStates.render.nFlashScale = (gameStates.render.nFlashScale + I2X (3))/4; // gets in range 0.5 to 1.0 } else { flash_ang += (fixang) FixMul (gameStates.render.nFlashRate, gameData.time.xFrame); FixFastSinCos (flash_ang, &gameStates.render.nFlashScale, NULL); gameStates.render.nFlashScale = (gameStates.render.nFlashScale + I2X (1))/2; if (gameStates.app.nDifficultyLevel == 0) gameStates.render.nFlashScale = (gameStates.render.nFlashScale+I2X (3))/4; } }
void SeismicDisturbanceFrame (void) { if (gameStates.gameplay.seismic.nShakeFrequency) { if (((gameStates.gameplay.seismic.nStartTime < gameData.time.xGame) && (gameStates.gameplay.seismic.nEndTime > gameData.time.xGame)) || StartSeismicDisturbance()) { fix deltaTime = gameData.time.xGame - gameStates.gameplay.seismic.nStartTime; int fc, rx, rz; fix h; fc = abs(deltaTime - (gameStates.gameplay.seismic.nEndTime - gameStates.gameplay.seismic.nStartTime) / 2); fc /= F1_0 / 16; if (fc > 16) fc = 16; else if (fc == 0) fc = 1; gameStates.gameplay.seismic.nVolume += fc; h = 3 * F1_0 / 16 + (F1_0 * (16 - fc)) / 32; rx = FixMul(d_rand() - 16384, h); rz = FixMul(d_rand() - 16384, h); gameData.objs.console->mType.physInfo.rotVel.p.x += rx; gameData.objs.console->mType.physInfo.rotVel.p.z += rz; // Shake the buddy! if (gameData.escort.nObjNum != -1) { gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.x += rx*4; gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.z += rz*4; } // Shake a guided missile! gameStates.gameplay.seismic.nMagnitude += rx; } } }
//------------------------------------------------------------------------------ //performs aspect scaling on global view matrix void ScaleMatrix (int bOglScale) { viewInfo.view [1] = viewInfo.view [0]; //so we can use unscaled if we want viewInfo.viewf [1] = viewInfo.viewf [0]; //so we can use unscaled if we want viewInfo.scale = viewInfo.windowScale; if (viewInfo.zoom <= f1_0) //xZoom in by scaling z viewInfo.scale[Z] = FixMul (viewInfo.scale[Z], viewInfo.zoom); else { //xZoom out by scaling x&y fix s = FixDiv (f1_0, viewInfo.zoom); viewInfo.scale[X] = FixMul (viewInfo.scale[X], s); viewInfo.scale[Y] = FixMul (viewInfo.scale[Y], s); } viewInfo.scalef = viewInfo.scale.ToFloat(); //viewInfo.scale[X] = viewInfo.scale[Y] = viewInfo.scale[Z] = F1_0; //now scale matrix elements if (bOglScale) { //glScalef (X2F (viewInfo.scale[X]), X2F (viewInfo.scale[Y]), -X2F (viewInfo.scale[Z])); glScalef (1, 1, -1); } else { //VmVecScale (&viewInfo.view [0].rVec, viewInfo.scale[X]); //VmVecScale (&viewInfo.view [0].uVec, viewInfo.scale[Y]); //viewInfo.scale[X] = viewInfo.scale[Y] = viewInfo.scale[Z] = F1_0; viewInfo.view [0][FVEC] *= (-viewInfo.scale[Z]); glScalef (1, 1, 1); } viewInfo.viewf[0] = viewInfo.view[0].ToFloat(); }
fix ComputeHeadlightLightOnObject (tObject *objP) { int i; fix light; // Let's just illuminate players and robots for speed reasons, ok? if ((objP->nType != OBJ_ROBOT) && (objP->nType != OBJ_PLAYER)) return 0; light = 0; for (i = 0; i < nHeadLights; i++) { fix dot, dist; vmsVector vecToObj; tObject *lightObjP; lightObjP = Headlights [i]; VmVecSub (&vecToObj, &objP->position.vPos, &lightObjP->position.vPos); dist = VmVecNormalize (&vecToObj); if (dist > 0) { dot = VmVecDot (&lightObjP->position.mOrient.fVec, &vecToObj); if (dot < F1_0/2) light += FixDiv (HEADLIGHT_SCALE, FixMul (HEADLIGHT_SCALE, dist)); // Do the normal thing, but darken around headlight. else light += FixMul (FixMul (dot, dot), HEADLIGHT_SCALE)/8; } } return light; }
//------------------------------------------------------------------------------ //performs aspect scaling on global view matrix void ScaleMatrix (int bOglScale) { viewInfo.view [1] = viewInfo.view [0]; //so we can use unscaled if we want viewInfo.viewf [1] = viewInfo.viewf [0]; //so we can use unscaled if we want viewInfo.scale = viewInfo.windowScale; if (viewInfo.zoom <= f1_0) //xZoom in by scaling z viewInfo.scale.p.z = FixMul (viewInfo.scale.p.z, viewInfo.zoom); else { //xZoom out by scaling x&y fix s = FixDiv (f1_0, viewInfo.zoom); viewInfo.scale.p.x = FixMul (viewInfo.scale.p.x, s); viewInfo.scale.p.y = FixMul (viewInfo.scale.p.y, s); } //viewInfo.scale.p.x = viewInfo.scale.p.y = viewInfo.scale.p.z = F1_0; //now scale matrix elements if (bOglScale) //glScalef (f2fl (viewInfo.scale.p.x), f2fl (viewInfo.scale.p.y), -f2fl (viewInfo.scale.p.z)); glScalef (1, 1, -1); else { //VmVecScale (&viewInfo.view [0].rVec, viewInfo.scale.p.x); //VmVecScale (&viewInfo.view [0].uVec, viewInfo.scale.p.y); //viewInfo.scale.p.x = viewInfo.scale.p.y = viewInfo.scale.p.z = F1_0; VmVecScale (&viewInfo.view [0].fVec, -viewInfo.scale.p.z); glScalef (1, 1, 1); } VmsMatToFloat (viewInfo.viewf, viewInfo.view); }
void WiggleObject (CObject *objP) { fix xWiggle; int nParent; CObject *pParent; if (gameStates.render.nShadowPass == 2) return; if (gameOpts->app.bEpilepticFriendly) return; if (!gameStates.app.bNostalgia && (!EGI_FLAG (nDrag, 0, 0, 0) || !EGI_FLAG (bWiggle, 1, 0, 1))) return; nParent = gameData.objs.parentObjs [objP->Index ()]; pParent = (nParent < 0) ? NULL : OBJECTS + nParent; FixFastSinCos (fix (gameData.time.xGame / gameStates.gameplay.slowmo [1].fSpeed), &xWiggle, NULL); if (gameData.time.xFrame < I2X (1))// Only scale wiggle if getting at least 1 FPS, to avoid causing the opposite problem. xWiggle = FixMul (xWiggle * 20, gameData.time.xFrame); //make wiggle fps-independent (based on pre-scaled amount of wiggle at 20 FPS) if (SPECTATOR (objP)) OBJPOS (objP)->vPos += (OBJPOS (objP)->mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle)) * (I2X (1) / 20); else if ((objP->info.nType == OBJ_PLAYER) || !pParent) objP->mType.physInfo.velocity += objP->info.position.mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle); else { objP->mType.physInfo.velocity += pParent->info.position.mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle); objP->info.position.vPos += objP->mType.physInfo.velocity * gameData.time.xFrame; } }
void CShrapnel::Move (void) { fix xSpeed = FixDiv (m_info.xSpeed, I2X (25) / 1000); CFixVector vOffs; time_t nTicks; if ((nTicks = gameStates.app.nSDLTicks - m_info.tUpdate) < 25) return; xSpeed = (fix) (xSpeed / gameStates.gameplay.slowmo [0].fSpeed); for (; nTicks >= 25; nTicks -= 25) { if (--(m_info.nTurn)) vOffs = m_info.vOffs; else { m_info.nTurn = ((m_info.xTTL > I2X (1) / 2) ? 2 : 4) + d_rand () % 4; vOffs = m_info.vDir; vOffs [X] = FixMul (vOffs [X], 2 * d_rand ()); vOffs [Y] = FixMul (vOffs [Y], 2 * d_rand ()); vOffs [Z] = FixMul (vOffs [Z], 2 * d_rand ()); CFixVector::Normalize (vOffs); m_info.vOffs = vOffs; } vOffs *= xSpeed; m_info.vPos += vOffs; } if (m_info.nSmoke >= 0) particleManager.SetPos (m_info.nSmoke, &m_info.vPos, NULL, -1); m_info.tUpdate = gameStates.app.nSDLTicks - nTicks; }
static void MixSoundSlot (struct sound_slot *sl, Uint8 *sldata, Uint8 *stream, int len) { Uint8 *streamend = stream + len; Uint8 *slend = sldata - sl->position + sl->length; Uint8 *sp = stream, s; signed char v; fix vl, vr; int x; if ((x = sl->pan) & 0x8000) { vl = 0x20000 - x * 2; vr = 0x10000; } else { vl = 0x10000; vr = x * 2; } vl = FixMul (vl, (x = sl->volume)); vr = FixMul (vr, x); while (sp < streamend) { if (sldata == slend) { if (!sl->looped) { sl->playing = 0; break; } sldata = sl->samples; } v = *(sldata++) - 0x80; s = *sp; *(sp++) = mix8 [s + FixMul (v, vl) + 0x80]; s = *sp; *(sp++) = mix8 [s + FixMul (v, vr) + 0x80]; } sl->position = (int) (sldata - sl->samples); }
int Blend (int i1, int i2) { Fixed smallFix, bigFix, tempFix; smallFix = ONE * i1; bigFix = ONE * i2; tempFix = FixMul (fract, bigFix) +FixMul (ONE-fract, smallFix); return (FixRound (tempFix)); }
// ------------------------------------------------------------------------------------------ // Move all sub-gameData.objs.objects in an tObject towards their goals. // Current orientation of tObject is at: polyObjInfo.animAngles // Goal orientation of tObject is at: aiInfo.goalAngles // Delta orientation of tObject is at: aiInfo.deltaAngles void AIFrameAnimation (tObject *objP) { int nObject = OBJ_IDX (objP); int joint; int nJoints = gameData.models.polyModels [objP->rType.polyObjInfo.nModel].nModels; for (joint=1; joint<nJoints; joint++) { fix delta_to_goal; fix scaled_delta_angle; vmsAngVec *curangp = &objP->rType.polyObjInfo.animAngles [joint]; vmsAngVec *goalangp = &gameData.ai.localInfo [nObject].goalAngles [joint]; vmsAngVec *deltaangp = &gameData.ai.localInfo [nObject].deltaAngles [joint]; Assert (nObject >= 0); delta_to_goal = goalangp->p - curangp->p; if (delta_to_goal > 32767) delta_to_goal = delta_to_goal - 65536; else if (delta_to_goal < -32767) delta_to_goal = 65536 + delta_to_goal; if (delta_to_goal) { scaled_delta_angle = FixMul (deltaangp->p, gameData.time.xFrame) * DELTA_ANG_SCALE; curangp->p += (fixang) scaled_delta_angle; if (abs (delta_to_goal) < abs (scaled_delta_angle)) curangp->p = goalangp->p; } delta_to_goal = goalangp->b - curangp->b; if (delta_to_goal > 32767) delta_to_goal = delta_to_goal - 65536; else if (delta_to_goal < -32767) delta_to_goal = 65536 + delta_to_goal; if (delta_to_goal) { scaled_delta_angle = FixMul (deltaangp->b, gameData.time.xFrame) * DELTA_ANG_SCALE; curangp->b += (fixang) scaled_delta_angle; if (abs (delta_to_goal) < abs (scaled_delta_angle)) curangp->b = goalangp->b; } delta_to_goal = goalangp->h - curangp->h; if (delta_to_goal > 32767) delta_to_goal = delta_to_goal - 65536; else if (delta_to_goal < -32767) delta_to_goal = 65536 + delta_to_goal; if (delta_to_goal) { scaled_delta_angle = FixMul (deltaangp->h, gameData.time.xFrame) * DELTA_ANG_SCALE; curangp->h += (fixang) scaled_delta_angle; if (abs (delta_to_goal) < abs (scaled_delta_angle)) curangp->h = goalangp->h; } } }
fix OmegaEnergy (fix xDeltaCharge) { fix xEnergyUsed; if (xDeltaCharge < 0) return -1; xEnergyUsed = FixMul (OMEGA_ENERGY_RATE, xDeltaCharge); if (gameStates.app.nDifficultyLevel < 2) xEnergyUsed = FixMul (xEnergyUsed, i2f (gameStates.app.nDifficultyLevel + 2) / 4); return xEnergyUsed; }
void CObject::RandomBump (fix xScale, fix xForce, bool bSound) { fix angle; angle = (d_rand () - I2X (1) / 4); mType.physInfo.rotVel [X] += FixMul (angle, xScale); angle = (d_rand () - I2X (1) / 4); mType.physInfo.rotVel [Z] += FixMul (angle, xScale); CFixVector vRand = CFixVector::Random (); Bump (vRand, xForce); if (bSound) audio.CreateObjectSound (SOUND_PLAYER_HIT_WALL, SOUNDCLASS_GENERIC, Index ()); }
bool G3DrawBitMap(vms_vector *pos,fix width,fix height,grs_bitmap *bm, int orientation) { vms_vector pv,v1; int i; r_bitmapc++; v1.z=0; glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); OglBindBmTex(bm); OglTexWrap(bm->glTexture,GL_CLAMP); glBegin(GL_QUADS); glColor3d(1.0,1.0,1.0); width = FixMul(width,viewInfo.scale.x); height = FixMul(height,viewInfo.scale.y); for (i = 0; i < 4; i++) { VmVecSub(&v1,pos,&viewInfo.position); VmVecRotate(&pv,&v1,&viewInfo.view); switch (i) { case 0: glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 0.0); pv.x+=-width; pv.y+=height; break; case 1: glMultiTexCoord2fARB(GL_TEXTURE0_ARB, bm->glTexture->u, 0.0); pv.x+=width; pv.y+=height; break; case 2: glMultiTexCoord2fARB(GL_TEXTURE0_ARB, bm->glTexture->u, bm->glTexture->v); pv.x+=width; pv.y+=-height; break; case 3: glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0, bm->glTexture->v); pv.x+=-width; pv.y+=-height; break; } glVertex3d (f2glf(pv.x), f2glf(pv.y), -f2glf(pv.z)); } glEnd(); //These next lines are important for later leave these here - Lehm 4/26/05 //glActiveTextureARB(GL_TEXTURE0_ARB); //glBindTexture(GL_TEXTURE_2D,0); //glDisable(GL_TEXTURE_2D); return 0; }
//changed on 980905 by adb to cleanup, add pan support and optimize mixer static void _CDECL_ AudioMixCallback(void *userdata, Uint8 *stream, int len) { Uint8 *streamend = stream + len; struct sound_slot *sl; if (!gameStates.sound.digi.bInitialized) return; memset(stream, 0x80, len); // fix "static" sound bug on Mac OS X for (sl = SoundSlots; sl < SoundSlots + MAX_SOUND_SLOTS; sl++) { if (sl->playing && sl->samples && sl->length) { #if 0 MixSoundSlot (sl, sl->samples + sl->position, stream, len); #else Uint8 *sldata = sl->samples + sl->position, *slend = sl->samples + sl->length; Uint8 *sp = stream, s; signed char v; fix vl, vr; int x; if ((x = sl->pan) & 0x8000) { vl = 0x20000 - x * 2; vr = 0x10000; } else { vl = 0x10000; vr = x * 2; } vl = FixMul (vl, (x = sl->volume)); vr = FixMul (vr, x); while (sp < streamend) { if (sldata == slend) { if (!sl->looped) { sl->playing = 0; break; } sldata = sl->samples; } v = *(sldata++) - 0x80; s = *sp; *(sp++) = mix8 [s + FixMul (v, vl) + 0x80]; s = *sp; *(sp++) = mix8 [s + FixMul (v, vr) + 0x80]; } sl->position = (int) (sldata - sl->samples); #endif } } }
//------------------------------------------------------------------------------ //process a continuously-spinning CObject void CObject::Spin (void) { CAngleVector rotangs; CFixMatrix rotmat, new_pm; Assert (info.movementType == MT_SPINNING); rotangs = CAngleVector::Create((fixang) FixMul (mType.spinRate [X], gameData.time.xFrame), (fixang) FixMul (mType.spinRate [Y], gameData.time.xFrame), (fixang) FixMul (mType.spinRate [Z], gameData.time.xFrame)); rotmat = CFixMatrix::Create (rotangs); new_pm = info.position.mOrient * rotmat; info.position.mOrient = new_pm; info.position.mOrient.CheckAndFix(); }
//------------------------------------------------------------------------------ //compute the corners of a rod. fills in vertbuf. int CalcRodCorners (g3sPoint *btmPoint, fix xBtmWidth, g3sPoint *topPoint, fix xTopWidth) { vmsVector vDelta, vTop, vTemp, vRodNorm; ubyte andCodes; int i; //compute vector from one point to other, do cross product with vector //from eye to get perpendicular vDelta = btmPoint->p3_vec - topPoint->p3_vec; //unscale for aspect #if RESCALE_ROD vDelta.p.x = FixDiv (vDelta.p.x, viewInfo.scale.p.x); vDelta.p.y = FixDiv (vDelta.p.y, viewInfo.scale.p.y); #endif //calc Perp vector //do lots of normalizing to prevent overflowing. When this code works, //it should be optimized vmsVector::Normalize(vDelta); vTop = topPoint->p3_vec; vmsVector::Normalize(vTop); vRodNorm = vmsVector::Cross(vDelta, vTop); vmsVector::Normalize(vRodNorm); //scale for aspect #if RESCALE_ROD vRodNorm.p.x = FixMul (vRodNorm.p.x, viewInfo.scale.p.x); vRodNorm.p.y = FixMul (vRodNorm.p.y, viewInfo.scale.p.y); #endif //now we have the usable edge. generate four points //vTop points vTemp = vRodNorm * xTopWidth; vTemp[Z] = 0; rodPoints [0].p3_vec = topPoint->p3_vec + vTemp; rodPoints [1].p3_vec = topPoint->p3_vec - vTemp; vTemp = vRodNorm * xBtmWidth; vTemp[Z] = 0; rodPoints [2].p3_vec = btmPoint->p3_vec - vTemp; rodPoints [3].p3_vec = btmPoint->p3_vec + vTemp; //now code the four points for (i = 0, andCodes = 0xff; i < 4; i++) andCodes &= G3EncodePoint (rodPoints + i); if (andCodes) return 1; //1 means off screen //clear flags for new points (not projected) for (i = 0; i < 4; i++) { rodPoints [i].p3_flags = 0; rodPoints [i].p3_index = -1; } return 0; }
void CreateSmallFireballOnObject (CObject *objP, fix size_scale, int bSound) { fix size; CFixVector vPos, vRand; short nSegment; vPos = objP->info.position.vPos; vRand = CFixVector::Random(); vRand *= (objP->info.xSize / 2); vPos += vRand; size = FixMul (size_scale, I2X (1) / 2 + d_rand () * 4 / 2); nSegment = FindSegByPos (vPos, objP->info.nSegment, 1, 0); if (nSegment != -1) { CObject *explObjP = /*Object*/CreateExplosion (nSegment, vPos, size, VCLIP_SMALL_EXPLOSION); if (!explObjP) return; AttachObject (objP, explObjP); if (bSound || (d_rand () < 8192)) { fix vol = I2X (1) / 2; if (objP->info.nType == OBJ_ROBOT) vol *= 2; audio.CreateObjectSound (SOUND_EXPLODING_WALL, SOUNDCLASS_EXPLOSION, objP->Index (), 0, vol); } } }
// ------------------------------------------------------------------------------------------ // Move all sub-OBJECTS in an CObject towards their goals. // Current orientation of CObject is at: polyObjInfo.animAngles // Goal orientation of CObject is at: aiInfo.goalAngles // Delta orientation of CObject is at: aiInfo.deltaAngles void AIFrameAnimation (CObject *objP) { int nObject = objP->Index (); int nJoint; int nJoints = gameData.models.polyModels [0][objP->rType.polyObjInfo.nModel].ModelCount (); for (nJoint = 1; nJoint < nJoints; nJoint++) { fix deltaToGoal; fix scaledDeltaAngle; CAngleVector* curAngP = &objP->rType.polyObjInfo.animAngles [nJoint]; CAngleVector* goalAngP = &gameData.ai.localInfo [nObject].goalAngles [nJoint]; CAngleVector* deltaAngP = &gameData.ai.localInfo [nObject].deltaAngles [nJoint]; Assert (nObject >= 0); for (int nAngle = 0; nAngle < 3; nAngle++) { deltaToGoal = (*goalAngP)[nAngle] - (*curAngP)[nAngle]; if (deltaToGoal > 32767) deltaToGoal -= 65536; else if (deltaToGoal < -32767) deltaToGoal += deltaToGoal; if (deltaToGoal) { scaledDeltaAngle = FixMul ((*deltaAngP)[nAngle], gameData.time.xFrame) * DELTA_ANG_SCALE; (*curAngP)[nAngle] += (fixang) scaledDeltaAngle; if (abs (deltaToGoal) < abs (scaledDeltaAngle)) (*curAngP)[nAngle] = (*goalAngP)[nAngle]; } } } }
void CHUD::DrawAfterburnerBar (void) { if (cockpit->Hide ()) return; int h, y; if (!(LOCALPLAYER.flags & PLAYER_FLAGS_AFTERBURNER)) return; //don't draw if don't have h = FixMul (gameData.physics.xAfterburnerCharge, 100); if (!gameOpts->render.cockpit.bTextGauges) { y = CCanvas::Current ()->Height () - (int) ((((gameData.app.nGameMode & GM_MULTI) ? 8 : 3) * m_info.nLineSpacing - 1) * m_info.yGaugeScale); CCanvas::Current ()->SetColorRGB (255, 0, 0, 255); glLineWidth (1); OglDrawEmptyRect (6, y, 6 + (int) (100 * m_info.xGaugeScale), y + (int) (9 * m_info.yGaugeScale)); CCanvas::Current ()->SetColorRGB (224, 0, 0, 128); OglDrawFilledRect (6, y, 6 + (int) (h * m_info.xGaugeScale), y + (int) (9 * m_info.yGaugeScale)); } if (gameData.demo.nState == ND_STATE_RECORDING) { if (gameData.physics.xAfterburnerCharge != m_history [gameStates.render.vr.nCurrentPage].afterburner) { NDRecordPlayerAfterburner (m_history [gameStates.render.vr.nCurrentPage].afterburner, gameData.physics.xAfterburnerCharge); m_history [gameStates.render.vr.nCurrentPage].afterburner = gameData.physics.xAfterburnerCharge; } } }
int OptimizePath (tPointSeg *pointSegP, int nSegs) { int i, j; CFixVector temp1, temp2; fix dot, mag1, mag2 = 0; for (i = 1; i < nSegs - 1; i += 2) { if (i == 1) { temp1 = pointSegP [i].point - pointSegP [i-1].point; mag1 = temp1.Mag(); } else { temp1 = temp2; mag1 = mag2; } temp2 = pointSegP [i + 1].point - pointSegP [i].point; mag2 = temp1.Mag(); dot = CFixVector::Dot (temp1, temp2); if (dot * 9/8 > FixMul (mag1, mag2)) pointSegP [i].nSegment = -1; } // Now, scan for points with nSegment == -1 for (i = j = 0; i < nSegs; i++) if (pointSegP [i].nSegment != -1) pointSegP [j++] = pointSegP [i]; return j; }
// ----------------------------------------------------------------------------- //see if a point is inside a face by projecting into 2d bool PointIsInQuad (CFixVector vRef, CFixVector* vertP, CFixVector vNormal) { CFixVector t, v0, v1; int i, j, iEdge, biggest; fix check_i, check_j; vec2d vEdge, vCheck; //now do 2d check to see if vRef is in side //project polygon onto plane by finding largest component of Normal t [X] = labs (vNormal [0]); t [Y] = labs (vNormal [1]); t [Z] = labs (vNormal [2]); if (t [X] > t [Y]) { if (t [X] > t [Z]) biggest = 0; else biggest = 2; } else { if (t [Y] > t [Z]) biggest = 1; else biggest = 2; } if (vNormal [biggest] > 0) { i = ijTable [biggest][0]; j = ijTable [biggest][1]; } else { i = ijTable [biggest][1]; j = ijTable [biggest][0]; } //now do the 2d problem in the i, j plane check_i = vRef [i]; check_j = vRef [j]; for (iEdge = 0; iEdge < 4; iEdge) { v0 = vertP [iEdge++]; v1 = vertP [iEdge % 4]; vEdge.i = v1 [i] - v0 [i]; vEdge.j = v1 [j] - v0 [j]; vCheck.i = check_i - v0 [i]; vCheck.j = check_j - v0 [j]; if (FixMul (vCheck.i, vEdge.j) - FixMul (vCheck.j, vEdge.i) < 0) return false; } return true; }
//------------------------------------------------------------------------------ //compute the corners of a rod. fills in vertbuf. int CalcRodCorners (g3sPoint *bot_point, fix bot_width, g3sPoint *top_point, fix top_width) { vmsVector delta_vec, top, tempv, rod_norm; ubyte codes_and; int i; //compute vector from one point to other, do cross product with vector //from eye to get perpendiclar VmVecSub (&delta_vec, &bot_point->p3_vec, &top_point->p3_vec); //unscale for aspect delta_vec.x = FixDiv (delta_vec.x, viewInfo.scale.x); delta_vec.y = FixDiv (delta_vec.y, viewInfo.scale.y); //calc perp vector //do lots of normalizing to prevent overflowing. When this code works, //it should be optimized VmVecNormalize (&delta_vec); VmVecCopyNormalize (&top, &top_point->p3_vec); VmVecCross (&rod_norm, &delta_vec, &top); VmVecNormalize (&rod_norm); //scale for aspect rod_norm.x = FixMul (rod_norm.x, viewInfo.scale.x); rod_norm.y = FixMul (rod_norm.y, viewInfo.scale.y); //now we have the usable edge. generate four points //top points VmVecCopyScale (&tempv, &rod_norm, top_width); tempv.z = 0; VmVecAdd (&rodPoints [0].p3_vec, &top_point->p3_vec, &tempv); VmVecSub (&rodPoints [1].p3_vec, &top_point->p3_vec, &tempv); VmVecCopyScale (&tempv, &rod_norm, bot_width); tempv.z = 0; VmVecSub (&rodPoints [2].p3_vec, &bot_point->p3_vec, &tempv); VmVecAdd (&rodPoints [3].p3_vec, &bot_point->p3_vec, &tempv); //now code the four points for (i = 0, codes_and = 0xff; i < 4; i++) codes_and &= G3EncodePoint (rodPoints + i); if (codes_and) return 1; //1 means off screen //clear flags for new points (not projected) for (i = 0; i < 4; i++) { rodPoints [i].p3Flags = 0; rodPoints [i].p3_index = -1; } return 0; }
void SetObjectTurnRoll (tObject *objP) { //if (!gameStates.app.bD1Mission) { fixang desired_bank = -FixMul (objP->mType.physInfo.rotVel.y, TURNROLL_SCALE); if (objP->mType.physInfo.turnRoll != desired_bank) { fixang delta_ang, max_roll; max_roll = FixMul (ROLL_RATE, gameData.time.xFrame); delta_ang = desired_bank - objP->mType.physInfo.turnRoll; if (labs (delta_ang) < max_roll) max_roll = delta_ang; else if (delta_ang < 0) max_roll = -max_roll; objP->mType.physInfo.turnRoll += max_roll; } } }
bool FontPlatformData::applyState(FS_STATE* font, float scale) const { ASSERT(font); ASSERT(m_name); if (FS_set_font(font, m_name) != SUCCESS) return false; if (FS_set_cmap(font, 3, 10) != SUCCESS) // First try Windows Unicode with surrogates... if (FS_set_cmap(font, 3, 1) != SUCCESS) // try normal Windows Unicode if (FS_set_cmap(font, 1, 0) != SUCCESS) return false; if (m_syntheticBold) { if (FS_set_bold_pct(font, floatToITypeFixed(0.06)) != SUCCESS) // 6% pseudo bold return false; } else { if (FS_set_bold_pct(font, 0) != SUCCESS) return false; } FS_FIXED skew = 0; if (m_syntheticOblique) skew = 13930; // 12 degrees FS_FIXED fixedScale = std::min(FixMul(floatToITypeFixed(scale), floatToITypeFixed(m_size)), MAXITYPEFONTSCALE); if (FS_set_scale(font, fixedScale, FixMul(fixedScale, skew), 0, fixedScale) != SUCCESS) return false; if (FS_set_flags(font, FLAGS_CMAP_OFF) != SUCCESS) return false; if (FS_set_flags(font, FLAGS_HINTS_OFF) != SUCCESS) return false; if (FS_set_flags(font, FLAGS_DEFAULT_CSM_OFF) != SUCCESS) return false; if (m_orientation == Vertical) { if (FS_set_flags(font, (m_textOrientation == TextOrientationVerticalRight) ? FLAGS_VERTICAL_ROTATE_LEFT_ON : FLAGS_VERTICAL_ON) != SUCCESS) return false; } return true; }
void CAudioChannel::Mix (ubyte* stream, int len) { if (m_info.bPlaying && m_info.sample.Buffer () && m_info.nLength) { #if 0 MixSoundchannelPot (channelP, m_info.sample + m_info.nPosition, stream, len); #else ubyte* streamEnd = stream + len; ubyte* channelData = reinterpret_cast<ubyte*> (m_info.sample.Buffer () + m_info.nPosition); ubyte* channelEnd = reinterpret_cast<ubyte*> (m_info.sample.Buffer () + m_info.nLength); ubyte* streamPos = stream, s; signed char v; fix vl, vr; int x; if ((x = m_info.nPan) & 0x8000) { vl = 0x20000 - x * 2; vr = 0x10000; } else { vl = 0x10000; vr = x * 2; } x = m_info.nVolume; vl = FixMul (vl, x); vr = FixMul (vr, x); while (streamPos < streamEnd) { if (channelData == channelEnd) { if (!m_info.bLooped) { m_info.bPlaying = 0; break; } channelData = m_info.sample.Buffer (); } v = *(channelData++) - 0x80; s = *streamPos; *streamPos++ = mix8 [s + FixMul (v, vl) + 0x80]; s = *streamPos; *streamPos++ = mix8 [s + FixMul (v, vr) + 0x80]; } m_info.nPosition = int (channelData - m_info.sample.Buffer ()); #endif } }
// If a smega missile been detonated, rock the mine! // This should be called every frame. // Maybe this should affect all robots, being called when they get their physics done. void RockTheMineFrame (void) { int i; for (i = 0; i < MAX_ESHAKER_DETONATES; i++) { if (eshakerDetonateTimes [i] != 0) { fix deltaTime = gameData.time.xGame - eshakerDetonateTimes [i]; if (!gameStates.gameplay.seismic.bSound) { DigiPlaySampleLooping ((short) gameStates.gameplay.seismic.nSound, F1_0, -1, -1); gameStates.gameplay.seismic.bSound = 1; gameStates.gameplay.seismic.nNextSoundTime = gameData.time.xGame + d_rand()/2; } if (deltaTime < ESHAKER_SHAKE_TIME) { // Control center destroyed, rock the tPlayer's ship. int fc, rx, rz; fix h; // -- fc = abs(deltaTime - ESHAKER_SHAKE_TIME/2); // Changed 10/23/95 to make decreasing for super mega missile. fc = (ESHAKER_SHAKE_TIME - deltaTime) / (ESHAKER_SHAKE_TIME / 16); if (fc > 16) fc = 16; else if (fc == 0) fc = 1; gameStates.gameplay.seismic.nVolume += fc; h = 3 * F1_0 / 16 + (F1_0 * (16 - fc)) / 32; rx = FixMul(d_rand() - 16384, h); rz = FixMul(d_rand() - 16384, h); gameData.objs.console->mType.physInfo.rotVel.p.x += rx; gameData.objs.console->mType.physInfo.rotVel.p.z += rz; // Shake the buddy! if (gameData.escort.nObjNum != -1) { gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.x += rx*4; gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.z += rz*4; } // Shake a guided missile! gameStates.gameplay.seismic.nMagnitude += rx; } else eshakerDetonateTimes [i] = 0; } } // Hook in the rumble sound effect here. }
const CFixMatrix CFixMatrix::Inverse (void) { fix xDet = Det (); CFixMatrix m; m.m_data.mat [RVEC][X] = FixDiv (FixMul (m_data.mat [UVEC][Y], m_data.mat [FVEC][Z]) - FixMul (m_data.mat [UVEC][Z], m_data.mat [FVEC][Y]), xDet); m.m_data.mat [RVEC][Y] = FixDiv (FixMul (m_data.mat [RVEC][Z], m_data.mat [FVEC][Y]) - FixMul (m_data.mat [RVEC][Y], m_data.mat [FVEC][Z]), xDet); m.m_data.mat [RVEC][Z] = FixDiv (FixMul (m_data.mat [RVEC][Y], m_data.mat [UVEC][Z]) - FixMul (m_data.mat [RVEC][Z], m_data.mat [UVEC][Y]), xDet); m.m_data.mat [UVEC][X] = FixDiv (FixMul (m_data.mat [UVEC][Z], m_data.mat [FVEC][X]) - FixMul (m_data.mat [UVEC][X], m_data.mat [FVEC][Z]), xDet); m.m_data.mat [UVEC][Y] = FixDiv (FixMul (m_data.mat [RVEC][X], m_data.mat [FVEC][Z]) - FixMul (m_data.mat [RVEC][Z], m_data.mat [FVEC][X]), xDet); m.m_data.mat [UVEC][Z] = FixDiv (FixMul (m_data.mat [RVEC][Z], m_data.mat [UVEC][X]) - FixMul (m_data.mat [RVEC][X], m_data.mat [UVEC][Z]), xDet); m.m_data.mat [FVEC][X] = FixDiv (FixMul (m_data.mat [UVEC][X], m_data.mat [FVEC][Y]) - FixMul (m_data.mat [UVEC][Y], m_data.mat [FVEC][X]), xDet); m.m_data.mat [FVEC][Y] = FixDiv (FixMul (m_data.mat [RVEC][Y], m_data.mat [FVEC][X]) - FixMul (m_data.mat [RVEC][X], m_data.mat [FVEC][Y]), xDet); m.m_data.mat [FVEC][Z] = FixDiv (FixMul (m_data.mat [RVEC][X], m_data.mat [UVEC][Y]) - FixMul (m_data.mat [RVEC][Y], m_data.mat [UVEC][X]), xDet); return m; }
//------------------------------------------------------------------------------ //do special cloaked render int DrawCloakedObject (CObject *objP, fix light, fix *glow, fix xCloakStartTime, fix xCloakEndTime) { tObjTransformation *posP = OBJPOS (objP); tCloakInfo ci; int bOk = 0; if (gameStates.render.bQueryCoronas) return 1; GetCloakInfo (objP, xCloakStartTime, xCloakEndTime, &ci); if (ci.bFading < 0) { fix xNewLight, xSaveGlow; tBitmapIndex * altTextures = NULL; if (objP->rType.polyObjInfo.nAltTextures > 0) altTextures = mpTextureIndex [objP->rType.polyObjInfo.nAltTextures - 1]; xNewLight = FixMul (light, ci.xLightScale); xSaveGlow = glow [0]; glow [0] = FixMul (glow [0], ci.xLightScale); gameData.models.nLightScale = ci.xLightScale; bOk = DrawPolyModel (objP, &posP->vPos, &posP->mOrient, reinterpret_cast<CAngleVector*> (&objP->rType.polyObjInfo.animAngles), objP->rType.polyObjInfo.nModel, objP->rType.polyObjInfo.nSubObjFlags, xNewLight, glow, altTextures, NULL); gameData.models.nLightScale = 0; glow [0] = xSaveGlow; } else { gameStates.render.bCloaked = 1; gameStates.render.grAlpha = GrAlpha (ci.nFadeValue); CCanvas::Current ()->SetColorRGB (0, 0, 0, 255); //set to black (matters for s3) fpDrawTexPolyMulti = G3DrawTexPolyFlat; bOk = DrawPolyModel (objP, &posP->vPos, &posP->mOrient, reinterpret_cast<CAngleVector*> (&objP->rType.polyObjInfo.animAngles), objP->rType.polyObjInfo.nModel, objP->rType.polyObjInfo.nSubObjFlags, light, glow, NULL, NULL); fpDrawTexPolyMulti = G3DrawTexPolyMulti; gameStates.render.grAlpha = 1.0f; gameStates.render.bCloaked = 0; } return bOk; }
void NetworkHandlePingReturn (ubyte nPlayer) { if ((nPlayer >= gameData.multiplayer.nPlayers) || !pingStats [nPlayer].launchTime) { #if 1 console.printf (CON_DBG, "Got invalid PING RETURN from %s!\n", gameData.multiplayer.players [nPlayer].callsign); #endif return; } xPingReturnTime = TimerGetFixedSeconds (); pingStats [nPlayer].ping = X2I (FixMul (xPingReturnTime - pingStats [nPlayer].launchTime, I2X (1000))); if (!gameStates.render.cockpit.bShowPingStats) HUDInitMessage ("Ping time for %s is %d ms!", gameData.multiplayer.players [nPlayer].callsign, pingStats [nPlayer].ping); pingStats [nPlayer].launchTime = 0; pingStats [nPlayer].received++; }
void Mix_VolPan (int channel, int vol, int pan) { #if USE_SDL_MIXER if (gameOpts->sound.bUseSDLMixer && (channel >= 0)) { if (vol) { vol = (FixMul (vol, gameStates.sound.digi.nVolume) + (SOUND_MAX_VOLUME / MIX_MAX_VOLUME) / 2) / (SOUND_MAX_VOLUME / MIX_MAX_VOLUME); if (!vol) vol = 1; Mix_Volume (channel, vol); pan /= (32767 / 127); Mix_SetPanning (channel, (ubyte) pan, (ubyte) (254 - pan)); } } #endif }