Repository navigation
Expand file tree
/
Copy pathcontrol.c
More file actions
126 lines (119 loc) · 3.39 KB
/
Copy pathcontrol.c
File metadata and controls
126 lines (119 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
///
// control.c
// =========
//
// Implementation of the function to convert key input into simplified actions
// for the faststack engine.
///
#include "engine.h"
#include "control.h"
#include "internal.h"
i32 popcount(u32 x)
{
i32 c = 0;
while (x) {
c += x & 1;
x >>= 1;
}
return c;
}
///
// Transform the current input state into a simple set of actions for the
// engine to apply.
//
// `keys` is an integer with bits set depending on the state of the specified
// key. The bits set correspond to the `FST_VK_FLAG` enum in `fsControl.h`.
///
void fsVirtualKeysToInput(FSInput *dst, u32 keys, const FSEngine *f, FSControl *c)
{
u32 lastTickKeys = c->lastKeys;
u32 newKeys = keys & ~lastTickKeys;
c->lastKeys = keys;
c->currentKeys &= keys;
keys &= ~c->currentKeys;
newKeys &= keys;
dst->currentKeys = keys;
dst->newKeysCount = popcount(newKeys);
if (keys & FST_VK_FLAG_LEFT) {
if (c->dasCounter > TICKS(-f->dasDelay)) {
if (c->dasCounter >= 0) {
c->dasCounter = -1;
dst->movement = -1;
}
else {
c->dasCounter -= 1;
}
}
else {
int dasSpeed = f->dasSpeed;
if (dasSpeed) {
dst->movement = -1;
c->dasCounter += dasSpeed - 1;
}
else {
dst->movement = -f->fieldWidth;
}
}
}
else if (keys & FST_VK_FLAG_RIGHT) {
if (c->dasCounter < TICKS(f->dasDelay)) {
if (c->dasCounter <= 0) {
c->dasCounter = 1;
dst->movement = 1;
}
else {
c->dasCounter += 1;
}
}
else {
int dasSpeed = f->dasSpeed;
if (dasSpeed) {
dst->movement = 1;
c->dasCounter -= dasSpeed - 1;
}
else {
dst->movement = f->fieldWidth;
}
}
}
else {
c->dasCounter = 0;
}
const int sdKeysToCheck = f->oneShotSoftDrop ? newKeys : keys;
if (sdKeysToCheck & FST_VK_FLAG_DOWN) {
// Note: This fix/unfix is a little messy and should be consolidated
dst->gravity = unfixflr(f->msPerTick * f->softDropGravity);
}
// A double keypress should only affect finesse once. Arguably we want two
// flags here but unsure how common this case would be anyway.
if (newKeys & (FST_VK_FLAG_RIGHT | FST_VK_FLAG_LEFT)) {
dst->extra |= FST_INPUT_FINESSE_MOVE;
}
if (newKeys & FST_VK_FLAG_ROTL) {
dst->rotation -= 1;
dst->extra |= FST_INPUT_FINESSE_ROTATE;
}
if (newKeys & FST_VK_FLAG_ROTR) {
dst->rotation += 1;
dst->extra |= FST_INPUT_FINESSE_ROTATE;
}
// A 180 degree rotation takes priority over any 90 degree rotations
if (newKeys & FST_VK_FLAG_ROTH) {
dst->rotation = 2;
dst->extra |= FST_INPUT_FINESSE_ROTATE;
}
if (newKeys & FST_VK_FLAG_HOLD) {
dst->extra |= FST_INPUT_HOLD;
}
if (newKeys & FST_VK_FLAG_UP) {
dst->gravity = f->fieldHeight;
dst->extra |= FST_INPUT_HARD_DROP;
dst->extra |= FST_INPUT_LOCK;
}
if (newKeys & FST_VK_FLAG_RESTART) {
dst->extra |= FST_INPUT_RESTART;
}
if (newKeys & FST_VK_FLAG_QUIT) {
dst->extra |= FST_INPUT_QUIT;
}
}