Files
scummvm-cursorfix/engines/twine/scene/buggy.cpp
2026-02-02 04:50:13 +01:00

710 lines
18 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "twine/scene/buggy.h"
#include "twine/audio/sound.h"
#include "twine/scene/actor.h"
#include "twine/scene/animations.h"
#include "twine/scene/collision.h"
#include "twine/scene/movements.h"
#include "twine/scene/scene.h"
#include "twine/shared.h"
#include "twine/twine.h"
#define MAX_SAMPLE_PITCH 11000
#define MIN_SAMPLE_PITCH2 5000
#define MAX_SAMPLE_PITCH2 8500
#define MAX_SPEED 3800
#define TEMPO_GEAR 1200 // speed change
#define SAMPLE_BUGGY 109
namespace TwinE {
void Buggy::initBuggy(uint8 numobj, uint32 flaginit) {
S_BUGGY *ptb = &ListBuggy[0];
ActorStruct *ptrobj = _engine->_scene->getActor(numobj);
// So that the objects follow their tracks without being interrupted
// by the buggy (too bad, it will be pushed)
ptrobj->_flags.bCanBePushed = true;
ptrobj->_flags.bCanDrown = true;
if (flaginit == 2 // we force the repositioning of the buggy
|| (flaginit && !NumBuggy)) // first initialization
// because the empty buggy cannot be Twinsen
{
ptb->Cube = _engine->_scene->_numCube; // Port-Ludo (Desert)
ptb->X = ptrobj->_posObj.x;
ptb->Y = ptrobj->_posObj.y;
ptb->Z = ptrobj->_posObj.z;
ptb->Beta = ptrobj->_beta;
_engine->_actor->initBody(BodyType::btNormal, numobj);
NumBuggy = (uint8)(numobj | BUGGY_PRESENT);
} else if (NumBuggy) {
if (_engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX)->_move != ControlMode::kBuggyManual && _engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX)->_move != ControlMode::kBuggy) {
int32 x, y;
if (_engine->_scene->_numCube == ptb->Cube) {
ptrobj->_posObj.x = ptb->X;
ptrobj->_posObj.y = ptb->Y;
ptrobj->_posObj.z = ptb->Z;
ptrobj->_beta = ptb->Beta;
_engine->_actor->initBody(BodyType::btNormal, numobj);
} else if (_engine->_scene->loadSceneCubeXY(ptb->Cube, &x, &y)) {
x -= _engine->_scene->_currentCubeX;
y -= _engine->_scene->_currentCubeY;
ptrobj->_posObj.x = ptb->X + x * 32768;
ptrobj->_posObj.y = ptb->Y;
ptrobj->_posObj.z = ptb->Z + y * 32768;
ptrobj->_beta = ptb->Beta;
ptrobj->_flags.bNoShadow = 1;
ptrobj->_flags.bIsBackgrounded = 1;
ptrobj->_flags.bNoElectricShock = 1;
ptrobj->_flags.bHasZBuffer = 1;
_engine->_actor->initBody(BodyType::btNormal, numobj);
} else {
_engine->_actor->initBody(BodyType::btNone, numobj);
}
_engine->_movements->clearRealAngle(ptrobj);
} else {
_engine->_actor->initBody(BodyType::btNone, numobj);
}
NumBuggy = (uint8)(numobj | BUGGY_PRESENT);
} else {
_engine->_actor->initBody(BodyType::btNone, numobj);
}
}
void Buggy::resetBuggy() {
S_BUGGY *ptb = &ListBuggy[0];
NumBuggy = 0;
ptb->Cube = 0;
}
void Buggy::takeBuggy() {
int32 sample;
ActorStruct *ptrobj = _engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX);
S_BUGGY *ptb = &ListBuggy[0];
ptb->SpeedRot = 1024;
// TODO: ptb->LastTimer = TimerRefHR;
// TODO: ObjectClear(&ptrobj);
// Shielding in case the Buggy moved (being pushed, for example).
ptb->X = _engine->_scene->getActor(NUM_BUGGY)->_posObj.x;
ptb->Y = _engine->_scene->getActor(NUM_BUGGY)->_posObj.y;
ptb->Z = _engine->_scene->getActor(NUM_BUGGY)->_posObj.z;
ptrobj->_posObj.x = ptb->X;
ptrobj->_posObj.y = ptb->Y;
ptrobj->_posObj.z = ptb->Z;
ptrobj->_beta = ptb->Beta;
_engine->_movements->clearRealAngle(ptrobj); // To avoid crushing the beta.
ptrobj->_workFlags.bMANUAL_INTER_FRAME = true;
ptrobj->_flags.bHasZBuffer = true;
// TODO: _engine->_actor->setBehaviour(HeroBehaviourType::kBUGGY);
// Switch Buggy Scenario to NoBody.
_engine->_actor->initBody(BodyType::btNone, NUM_BUGGY);
if (ptrobj->SampleAlways) {
_engine->_sound->stopSample(ptrobj->SampleAlways);
ptrobj->SampleAlways = 0;
}
sample = SAMPLE_BUGGY;
if (_engine->_sound->isSamplePlaying(sample)) {
_engine->_sound->stopSample(sample);
}
ptrobj->SampleVolume = 20;
// TODO: ParmSampleVolume = ptrobj->SampleVolume;
Gear = 0;
TimerGear = 0;
// TODO: ptrobj->SampleAlways = _engine->_sound->playSample(SAMPLE_BUGGY, 4096, 0, 0,
// ptrobj->_posObj.x, ptrobj->_posObj.y, ptrobj->_posObj.z);
}
#if 0
static void ObjectClear(T_OBJ *ptb3d) {
memset(ptb3d, 0, sizeof(T_OBJ));
ptb3d.OBJ_3D.Body, -1
ptb3d.OBJ_3D.NextBody, -1
ptb3d.OBJ_3D.Texture, -1
ptb3d.OBJ_3D.NextTexture, -1
ptb3d.OBJ_3D.Anim, -1
}
#endif
void Buggy::leaveBuggy(HeroBehaviourType behaviour) {
int32 sample;
ActorStruct *ptrobj = _engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX);
S_BUGGY *ptb = &ListBuggy[0];
sample = SAMPLE_BUGGY;
if (_engine->_sound->isSamplePlaying(sample)) {
_engine->_sound->stopSample(sample);
ptrobj->SampleAlways = 0;
}
ptb->X = ptrobj->_posObj.x;
ptb->Y = ptrobj->_posObj.y;
ptb->Z = ptrobj->_posObj.z;
ptb->Beta = ptrobj->_beta;
ptb->Cube = _engine->_scene->_numCube;
// TODO: ObjectClear(ptrobj);
ptrobj->_workFlags.bMANUAL_INTER_FRAME = 0;
ptrobj->_flags.bHasZBuffer = 0;
_engine->_actor->initBody(BodyType::btTunic, OWN_ACTOR_SCENE_INDEX);
_engine->_actor->setBehaviour(behaviour);
// Restore scenario buggy.
ptrobj = _engine->_scene->getActor(NUM_BUGGY);
ptrobj->_posObj.x = ptb->X;
ptrobj->_posObj.y = ptb->Y;
ptrobj->_posObj.z = ptb->Z;
ptrobj->_beta = ptb->Beta;
ptrobj->_brickSound = _engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX)->_brickSound;
_engine->_movements->clearRealAngle(ptrobj); // To avoid crushing the beta
_engine->_actor->initBody(BodyType::btNormal, NUM_BUGGY);
// Search for a free position for Twinsen nearby.
_engine->_actor->posObjectAroundAnother(NUM_BUGGY, OWN_ACTOR_SCENE_INDEX);
}
#if 0
struct T_HALF_POLY {
uint32 Bank : 4; // coul bank poly
uint32 TexFlag : 2; // flag texture 00 rien 01 triste 10 flat 11 gouraud
uint32 PolyFlag : 2; // flag poly 00 rien 01 flat 10 gouraud 11 dither
uint32 SampleStep : 4; // sample pas twinsen
uint32 CodeJeu : 4; // code jeu
uint32 Sens : 1; // sens diagonale
uint32 Col : 1;
uint32 Dummy : 1;
uint32 IndexTex : 13; // index texture 8192
}; // 1 long
struct T_HALF_TEX {
uint16 Tx0;
uint16 Ty0;
uint16 Tx1;
uint16 Ty1;
uint16 Tx2;
uint16 Ty2;
}; // 2 Longs
int32 CalculAltitudeObjet(int32 x, int32 z, int32 cj) {
int32 y0, y1, y2, y3;
int32 dx, dz;
int32 dz0, dz1;
dx = x >> 9; // div512
dz = z >> 9; // div512
if ((dx < 0) || (dx > 63))
return -1;
if ((dz < 0) || (dz > 63))
return -1;
x &= 511;
z &= 511;
dz0 = dz * 65;
dz1 = dz0 + 65;
//---------------------------------------------------------------
if (cj == -1) {
T_HALF_POLY *mappoly = &MapPolyGround[dz * 64 * 2 + dx * 2];
if (mappoly->Sens == 0) // poly séparé par ligne reliant point 0 et 2
{
if (x >= z) // poly de droite
{
mappoly++;
}
} else // poly séparé par ligne reliant point 1 et 3
{
if (511 - x <= z) // poly de droite
{
mappoly++;
}
}
cj = (uint8)mappoly->CodeJeu;
}
//--------------------------------------------------------------
y0 = MapSommetY[dz0 + dx];
y1 = MapSommetY[dz1 + dx];
y2 = MapSommetY[dz1 + (dx + 1)];
y3 = MapSommetY[dz0 + (dx + 1)];
if (cj == CJ_FOOT_WATER OR cj == CJ_WATER) {
uint8 *i = &MapIntensity[dz0 + dx];
y0 += (i[0] >> 4) * -200;
y1 += (i[65] >> 4) * -200;
y2 += (i[65 + 1] >> 4) * -200;
y3 += (i[1] >> 4) * -200;
}
if (MapPolyGround[dz * 64 * 2 + dx * 2].Sens == 0) // poly séparé par ligne reliant point 0 et 2
{
if (x < z) // poly de gauche
{
return (y0 + ((y1 - y0) * z + (y2 - y1) * x) / 512);
} else // poly de droite
{
return (y0 + ((y3 - y0) * x + (y2 - y3) * z) / 512);
}
} else // poly séparé par ligne reliant point 1 et 3
{
if (511 - x > z) // poly de gauche
{
return (y0 + ((y3 - y0) * x + (y1 - y0) * z) / 512);
} else // poly de droite
{
return (y1 + ((y2 - y1) * x + (y3 - y2) * (511 - z)) / 512);
}
}
}
#endif
void Buggy::doAnimBuggy(ActorStruct *ptrobj) {
#if 0
int32 x1, y1, z1, yw;
S_BUGGY *ptb = &ListBuggy[0];
T_OBJ_3D *ptb3d = &ptrobj->Obj;
// wheels rot
int32 c, d;
int32 x, y, z;
// Trick to avoid crushing the groups in AffOneObject().
ObjectSetInterFrame(ptb3d);
if (ptrobj->_workFlags.bIsFalling || ptrobj->_workFlags.bANIM_MASTER_GRAVITY) {
return;
}
LongRotate(0, ptb->SpeedInc * 1024, ptb3d->Beta);
ptrobj->_processActor.x = ptb3d->X + X0 / 1024;
ptrobj->_processActor.z = ptb3d->Z + Z0 / 1024;
// Ideal altitude
yw = CalculAltitudeObjet(ptrobj->_processActor.x, ptrobj->_processActor.z, -1); // Ground Y for XZ
// test altitude #2: Forbidden triangles
// Front left wheel direction
ptb3d->CurrentFrame[3].Beta = (int16)ptb->BetaWheel;
// Front right wheel direction
ptb3d->CurrentFrame[6].Beta = (int16)ptb->BetaWheel;
// Management of 4 separate wheels.
// front right wheel
LongRotate(-400, 400, ptb3d->Beta);
x = ptrobj->_processActor.x + X0;
z = ptrobj->_processActor.z + Z0;
y = yw;
if (x >= 0 && x < 32768 && z >= 0 && z < 32768) {
y += CalculAltitudeObjet(x, z, -1);
}
c = (260 * 31415) / 1000; // Circumference * 10
d = Distance3D(ptb->Wheel[0].X, ptb->Wheel[0].Y, ptb->Wheel[0].Z, x, y, z);
if (ptb->Speed >= 0) {
ptb->Wheel[0].Angle += (4096 * 10 * d) / c;
} else {
ptb->Wheel[0].Angle -= (4096 * 10 * d) / c;
}
ptb->Wheel[0].X = x;
ptb->Wheel[0].Y = y;
ptb->Wheel[0].Z = z;
// front left wheel
LongRotate(400, 400, ptb3d->Beta);
x = ptrobj->_processActor.x + X0;
z = ptrobj->_processActor.z + Z0;
y = yw;
if (x >= 0 && x < 32768 && z >= 0 && z < 32768) {
y += CalculAltitudeObjet(x, z, -1);
}
c = (260 * 31415) / 1000; // Circumference * 10
d = Distance3D(ptb->Wheel[1].X, ptb->Wheel[1].Y, ptb->Wheel[1].Z, x, y, z);
if (ptb->Speed >= 0) {
ptb->Wheel[1].Angle += (4096 * 10 * d) / c;
} else {
ptb->Wheel[1].Angle -= (4096 * 10 * d) / c;
}
ptb->Wheel[1].X = x;
ptb->Wheel[1].Y = y;
ptb->Wheel[1].Z = z;
// back left wheel
LongRotate(400, -350, ptb3d->Beta);
x = ptrobj->_processActor.x + X0;
z = ptrobj->_processActor.z + Z0;
y = yw;
if (x >= 0 && x < 32768 && z >= 0 && z < 32768) {
y += CalculAltitudeObjet(x, z, -1);
}
c = (360 * 31415) / 1000; // Circumference * 10
d = Distance3D(ptb->Wheel[2].X, ptb->Wheel[2].Y, ptb->Wheel[2].Z, x, y, z);
if (ptb->Speed >= 0) {
ptb->Wheel[2].Angle += (4096 * 10 * d) / c;
} else {
ptb->Wheel[2].Angle -= (4096 * 10 * d) / c;
}
ptb->Wheel[2].X = x;
ptb->Wheel[2].Y = y;
ptb->Wheel[2].Z = z;
// back right wheel
LongRotate(-400, -350, ptb3d->Beta);
x = ptrobj->_processActor.x + X0;
z = ptrobj->_processActor.z + Z0;
y = yw;
if (x >= 0 && x < 32768 && z >= 0 && z < 32768) {
y += CalculAltitudeObjet(x, z, -1);
}
c = (360 * 31415) / 1000; // Circumference * 10
d = Distance3D(ptb->Wheel[3].X, ptb->Wheel[3].Y, ptb->Wheel[3].Z, x, y, z);
if (ptb->Speed >= 0) {
ptb->Wheel[3].Angle += (4096 * 10 * d) / c;
} else {
ptb->Wheel[3].Angle -= (4096 * 10 * d) / c;
}
ptb->Wheel[3].X = x;
ptb->Wheel[3].Y = y;
ptb->Wheel[3].Z = z;
// front right wheel
ptb3d->CurrentFrame[4].Alpha = (int16)ptb->Wheel[1].Angle;
// front left wheel
ptb3d->CurrentFrame[7].Alpha = (int16)ptb->Wheel[0].Angle;
// back left wheel
ptb3d->CurrentFrame[11].Alpha = (int16)ptb->Wheel[2].Angle;
// back right wheel
ptb3d->CurrentFrame[9].Alpha = (int16)ptb->Wheel[3].Angle;
// Car inclination (pitch)
ptb3d->CurrentFrame[1].Type = 0;
LongRotate(0, 400, ptb3d->Beta);
x1 = X0;
z1 = Z0;
LongRotate(0, -400, ptb3d->Beta);
if (Nxw + x1 >= 0 && Nxw + x1 < 32768 && Nzw + z1 >= 0 && Nzw + z1 < 32768) {
y = CalculAltitudeObjet(Nxw + x1, Nzw + z1, -1);
} else {
y = yw;
}
if (Nxw + X0 >= 0 && Nxw + X0 < 32768 && Nzw + Z0 >= 0 && Nzw + Z0 < 32768) {
y1 = CalculAltitudeObjet(Nxw + X0, Nzw + Z0, -1);
} else {
y1 = yw;
}
ptb3d->CurrentFrame[1].Alpha = (int16)(1024 - GetAngle2D(0, y, 800, y1));
ptb->Alpha = ptb3d->CurrentFrame[1].Alpha;
// Car inclination (roll)
LongRotate(400, 0, ptb3d->Beta);
x1 = X0;
z1 = Z0;
LongRotate(-400, 0, ptb3d->Beta);
if (Nxw + X0 >= 0 && Nxw + X0 < 32768 && Nzw + Z0 >= 0 && Nzw + Z0 < 32768) {
y = CalculAltitudeObjet(Nxw + X0, Nzw + Z0, -1);
} else {
y = yw;
}
if (Nxw + x1 >= 0 && Nxw + x1 < 32768 && Nzw + z1 >= 0 && Nzw + z1 < 32768) {
y1 = CalculAltitudeObjet(Nxw + x1, Nzw + z1, -1);
} else {
y1 = yw;
}
ptb3d->CurrentFrame[1].Gamma = (int16)GetAngle2D(y, 0, y1, 800);
// Steering wheel
ptb3d->CurrentFrame[12].Gamma = (int16)-ptb->BetaWheel;
// Twinsen's head
ptb3d->CurrentFrame[14].Beta = (int16)ptb->BetaWheel;
#endif
}
void Buggy::moveBuggy(ActorStruct *ptrobj) {
#if 0
S_BUGGY *ptb = &ListBuggy[0];
T_OBJ_3D *ptb3d = &ptrobj->Obj;
int32 pitch = 0;
int32 flagattack = false;
int32 speedinc;
int32 rotlevel;
int32 timerhr, deltatimer;
timerhr = TimerRefHR;
deltatimer = timerhr - ptb->LastTimer;
if ((Input & I_THROW) && (PtrComportement->Flags & CF_WEAPON)) {
// Are we in mage?
if (TabInv[FLAG_TUNIQUE].IdObj3D == 0) {
_engine->_actor->initBody(BodyType::btTunicTir, OWN_ACTOR_SCENE_INDEX);
} else {
_engine->_actor->initBody(BodyType::btMageTir, OWN_ACTOR_SCENE_INDEX);
}
_engine->_animations->initAnim(AnimationTypes::kThrowBall, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
/* control direction pendant Aiming */
if (!ptrobj->_workFlags.bIsRotationByAnim) {
ptb3d->Beta += GetDeltaMove(&ptrobj->BoundAngle.Move);
ptb3d->Beta &= 4095;
_engine->_movements->initRealAngleConst(ptrobj);
}
_engine->_movements->_lastJoyFlag = true;
flagattack = true;
} else {
if (LastInput & I_THROW) {
// We finished shooting with the buggy,
// we close the hood
_engine->_actor->initBody(BodyType::btTunic, OWN_ACTOR_SCENE_INDEX);
_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
}
}
if (!flagattack && !ptrobj->_workFlags.bIsFalling && !ptrobj->_workFlags.bANIM_MASTER_GRAVITY) {
_engine->_movements->clearRealAngle(ptrobj);
if (_engine->_movements->_lastJoyFlag && (((Input & I_JOY) != LastMyJoy) || ((Input & I_FIRE) != LastMyFire))) {
_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
Pushing = false;
}
_engine->_movements->_lastJoyFlag = false;
// Pushing contains the number of the object being pushed
// So 1000 is an impossible value used as an initialization flag
// no animation
if (Pushing == 1000) {
_engine->_animations->initAnim(AnimationTypes::kStanding, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
Pushing = false;
}
if (Input & I_UP) {
if (Pushing) {
_engine->_animations->initAnim(AnimationTypes::kPush, ANIM_TEMPO, OWN_ACTOR_SCENE_INDEX);
_engine->_movements->_lastJoyFlag = true;
} else {
_engine->_animations->initAnim(AnimationTypes::kForward, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
_engine->_movements->_lastJoyFlag = true;
}
} else if (Input & I_DOWN) {
_engine->_animations->initAnim(AnimationTypes::kBackward, AnimType::kAnimationTypeRepeat, OWN_ACTOR_SCENE_INDEX);
_engine->_movements->_lastJoyFlag = true;
}
}
if (!ptrobj->_workFlags.bIsFalling && !ptrobj->_workFlags.bANIM_MASTER_GRAVITY) {
// check speed command
if ((Input & I_UP) // accelerating
&& !flagattack) {
ptb->Speed += deltatimer * 4;
if (!TimerGear)
TimerGear = TimerRefHR + TEMPO_GEAR;
else {
if (Gear < 0)
Gear = 0;
if (TimerRefHR > TimerGear && Gear < 2) {
Gear++;
TimerGear = TimerRefHR + TEMPO_GEAR;
}
}
} else if ((Input & I_DOWN) // brake / reverse
&& !flagattack) {
ptb->Speed -= deltatimer * 12;
Gear = -1;
TimerGear = 0;
} else // slow down
{
if (ptb->Speed > 0) {
ptb->Speed -= deltatimer * 7;
if (ptb->Speed < 0) {
ptb->Speed = 0;
}
}
if (ptb->Speed < 0) {
ptb->Speed += deltatimer * 7;
if (ptb->Speed > 0) {
ptb->Speed = 0;
}
}
Gear = 0;
TimerGear = 0;
}
if (ptb->Speed < -2000)
ptb->Speed = -2000;
if (ptb->Speed > MAX_SPEED)
ptb->Speed = MAX_SPEED;
speedinc = ptb->Speed * deltatimer / 1000;
} else {
speedinc = 0;
}
// check dir
if (!flagattack) {
if (Input & I_RIGHT) {
ptb->BetaWheel = -300;
if (ptb->Speed) {
rotlevel = -ptb->SpeedRot * speedinc / ptb->Speed;
} else {
rotlevel = 0;
}
} else if (Input & I_LEFT) {
ptb->BetaWheel = 300;
if (ptb->Speed) {
rotlevel = ptb->SpeedRot * speedinc / ptb->Speed;
} else {
rotlevel = 0;
}
} else {
ptb->BetaWheel = 0;
rotlevel = 0;
}
if (ptrobj->_staticFlags.bSKATING) {
ptb->Speed = 3000;
speedinc = ptb->Speed * deltatimer / 1000;
} else {
if (ptb->Speed >= 0) {
ptb3d->Beta += rotlevel;
} else {
ptb3d->Beta -= rotlevel;
}
ptb3d->Beta = ClampAngle(ptb3d->Beta);
}
} else {
ptb->BetaWheel = 0;
}
LastMyJoy = Input & I_JOY;
LastMyFire = Input & I_FIRE;
LastInput = Input;
ptb->LastTimer = timerhr;
ptb->SpeedInc = speedinc;
if (ptrobj->SampleAlways && _engine->_sound->isSamplePlaying(ptrobj->SampleAlways)) {
int32 pitch;
switch (Gear) {
case -1:
pitch = boundRuleThree(3000, MAX_SAMPLE_PITCH2, MAX_SPEED, ABS(ptb->Speed));
break;
case 0:
pitch = boundRuleThree(3000, MAX_SAMPLE_PITCH, MAX_SPEED, ABS(ptb->Speed));
if (pitch >= MAX_SAMPLE_PITCH)
TimerGear = 1;
break;
case 1:
pitch = boundRuleThree(MAX_SAMPLE_PITCH2, MIN_SAMPLE_PITCH2, TEMPO_GEAR, TimerGear - TimerRefHR);
break;
default:
pitch = MAX_SAMPLE_PITCH2;
}
_engine->_sound->ChangePitchbendSample(ptrobj->SampleAlways, pitch);
}
#endif
}
} // namespace TwinE