mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-12 22:02:49 +01:00
Detect event starts by double-buffering state
This commit is contained in:
parent
9f2fb5aa19
commit
57edc3648b
@ -55,14 +55,17 @@ struct GameInputState {
|
||||
*
|
||||
* For buttons, this will result in either 0 or 1.
|
||||
*/
|
||||
float currentLevels[_MaxControls] = {};
|
||||
float levels[_MaxControls] = {};
|
||||
|
||||
float operator[](Control c) const {
|
||||
return currentLevels[c];
|
||||
return levels[c];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if cotrol is held down
|
||||
*/
|
||||
bool pressed(Control c) const {
|
||||
return currentLevels[c] > kButtonOnThreshold;
|
||||
return levels[c] > kButtonOnThreshold;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -337,9 +337,9 @@ public:
|
||||
std::bitset<32> importExportUnused;
|
||||
|
||||
/**
|
||||
* State of the game input
|
||||
* State of the game input for the last 2 frames
|
||||
*/
|
||||
GameInputState input;
|
||||
GameInputState input[2];
|
||||
|
||||
/**
|
||||
* World to use for this state, this isn't saved, just used at runtime
|
||||
@ -362,6 +362,13 @@ public:
|
||||
* Removes a blip
|
||||
*/
|
||||
void removeBlip(int blip);
|
||||
|
||||
/**
|
||||
* Swaps input state
|
||||
*/
|
||||
void swapInputState() {
|
||||
input[1] = input[0];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2459,7 +2459,7 @@ bool opcode_00e1(const ScriptArguments& args, const ScriptPad player, const Scri
|
||||
// Hack: not implemented correctly.
|
||||
if (player == 0) {
|
||||
if (buttonID == 19) { // Look behind / sub mission
|
||||
return args.getState()->input.pressed(GameInputState::Submission);
|
||||
return args.getState()->input[0].pressed(GameInputState::Submission);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -420,6 +420,8 @@ int RWGame::run() {
|
||||
tick(GAME_TIMESTEP);
|
||||
RW_PROFILE_END();
|
||||
|
||||
getState()->swapInputState();
|
||||
|
||||
accum -= GAME_TIMESTEP;
|
||||
|
||||
// Throw away time if the accumulator reaches too high.
|
||||
|
@ -186,7 +186,18 @@ void IngameState::tick(float dt) {
|
||||
}
|
||||
|
||||
auto player = game->getPlayer();
|
||||
const auto& input = world->state->input;
|
||||
|
||||
auto input = [&](GameInputState::Control c) {
|
||||
return world->state->input[0][c];
|
||||
};
|
||||
auto pressed = [&](GameInputState::Control c) {
|
||||
return world->state->input[0].pressed(c) &&
|
||||
!world->state->input[1].pressed(c);
|
||||
};
|
||||
auto held = [&](GameInputState::Control c) {
|
||||
return world->state->input[0].pressed(c);
|
||||
};
|
||||
|
||||
if (player && player->isInputEnabled()) {
|
||||
float viewDistance = 4.f;
|
||||
switch (camMode) {
|
||||
@ -274,8 +285,8 @@ void IngameState::tick(float dt) {
|
||||
|
||||
// Non-topdown camera can orbit
|
||||
if (camMode != IngameState::CAMERA_TOPDOWN) {
|
||||
bool lookleft = input.pressed(GameInputState::LookLeft);
|
||||
bool lookright = input.pressed(GameInputState::LookRight);
|
||||
bool lookleft = held(GameInputState::LookLeft);
|
||||
bool lookright = held(GameInputState::LookRight);
|
||||
if ((lookleft || lookright) && vehicle != nullptr) {
|
||||
auto rotation = vehicle->getRotation();
|
||||
if (!lookright) {
|
||||
@ -319,17 +330,17 @@ void IngameState::tick(float dt) {
|
||||
angle = glm::quat(glm::vec3(0.f, 0.f, angleYaw));
|
||||
glm::vec3 movement;
|
||||
|
||||
movement.x = input[GameInputState::GoForward] -
|
||||
input[GameInputState::GoBackwards];
|
||||
movement.x = input(GameInputState::GoForward) -
|
||||
input(GameInputState::GoBackwards);
|
||||
movement.y =
|
||||
input[GameInputState::GoLeft] - input[GameInputState::GoRight];
|
||||
input(GameInputState::GoLeft) - input(GameInputState::GoRight);
|
||||
/// @todo replace with correct sprint behaviour
|
||||
float speed = input.pressed(GameInputState::Sprint) ? 2.f : 1.f;
|
||||
float speed = held(GameInputState::Sprint) ? 2.f : 1.f;
|
||||
|
||||
if (player->isInputEnabled()) {
|
||||
player->setRunning(!input.pressed(GameInputState::Walk));
|
||||
player->setRunning(!held(GameInputState::Walk));
|
||||
/// @todo find the correct behaviour for entering & exiting
|
||||
if (input.pressed(GameInputState::EnterExitVehicle)) {
|
||||
if (pressed(GameInputState::EnterExitVehicle)) {
|
||||
/// @todo move me
|
||||
if (player->getCharacter()->getCurrentVehicle()) {
|
||||
player->exitVehicle();
|
||||
@ -347,11 +358,10 @@ void IngameState::tick(float dt) {
|
||||
|
||||
if (player->getCharacter()->getCurrentVehicle()) {
|
||||
auto vehicle = player->getCharacter()->getCurrentVehicle();
|
||||
vehicle->setHandbraking(
|
||||
input.pressed(GameInputState::Handbrake));
|
||||
vehicle->setHandbraking(held(GameInputState::Handbrake));
|
||||
player->setMoveDirection(movement);
|
||||
} else {
|
||||
if (input.pressed(GameInputState::Jump)) {
|
||||
if (pressed(GameInputState::Jump)) {
|
||||
player->jump();
|
||||
}
|
||||
|
||||
@ -495,7 +505,7 @@ void IngameState::updateInputState(const SDL_Event& event) {
|
||||
case SDL_KEYUP: {
|
||||
auto sym = event.key.keysym.sym;
|
||||
auto level = event.type == SDL_KEYDOWN ? 1.f : 0.f;
|
||||
auto& levels = getWorld()->state->input.currentLevels;
|
||||
auto& levels = getWorld()->state->input[0].levels;
|
||||
|
||||
auto range = kDefaultControls.equal_range(sym);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
|
Loading…
Reference in New Issue
Block a user