Mercurial > hg > index.fcgi > lj > lj046-2players
comparison src/macro.c @ 0:c84446dfb3f5
initial add
author | paulo@localhost |
---|---|
date | Fri, 13 Mar 2009 00:39:12 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:dab37cb9f051 |
---|---|
1 /* Input handling for LOCKJAW Tetromino Game | |
2 | |
3 Copyright (C) 2006 Damian Yerrick <tepples+lj@spamcop.net> | |
4 | |
5 This work is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2 of the License, or | |
8 (at your option) any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Original game concept and design by Alexey Pajitnov. | |
20 The Software is not sponsored or endorsed by Alexey Pajitnov, Elorg, | |
21 or The Tetris Company LLC. | |
22 | |
23 */ | |
24 #include "lj.h" | |
25 #include "ljcontrol.h" | |
26 #include "ljreplay.h" | |
27 #include "pcjoy.h" | |
28 | |
29 // first is rotation (+1 = 90 deg clockwise) | |
30 // second is movement (+1 = right 1 block) | |
31 // third is gravity (+1 = down 1/8 block) | |
32 // fourth is extra actions (hold, lock) | |
33 LJInput macros[8] = { | |
34 { -1, 0, 0, 0 }, // default: alt. rotate left | |
35 { -2, 0, 0, 0 }, // default: rotate left twice | |
36 { 0, -9, 0, 0 }, // default: far left | |
37 { 0, 9, 0, 0 }, // default: far right | |
38 { 0, 0, 20*8, 0 }, // default: firm drop | |
39 { 0, 0, 0, LJI_HOLD }, // default: alternate hold | |
40 { 0, 0, 0, 0 }, | |
41 { 0, 0, 0, 0 } | |
42 }; | |
43 | |
44 void addMacrosToInput(LJInput *dst, LJBits keys) { | |
45 int rotation = dst->rotation; | |
46 int movement = dst->movement; | |
47 int gravity = dst->gravity; | |
48 int other = dst->other; | |
49 int macro; | |
50 | |
51 keys >>= 8; | |
52 for (macro = 0; | |
53 macro < 8; | |
54 keys >>= 1, ++macro) { | |
55 if (keys & 1) { | |
56 rotation += macros[macro].rotation; | |
57 movement += macros[macro].movement; | |
58 gravity += macros[macro].gravity; | |
59 other |= macros[macro].other; | |
60 } | |
61 } | |
62 | |
63 // Clip rotation to [-3, +3] | |
64 rotation -= rotation / 4 * 4; | |
65 | |
66 // Clip movement to playfield width | |
67 if (movement < (int)-LJ_PF_WID) { | |
68 movement = -LJ_PF_WID; | |
69 } else if (movement > (int)LJ_PF_WID) { | |
70 movement = LJ_PF_WID; | |
71 } | |
72 | |
73 // Clip gravity to playfield height | |
74 if (gravity > LJ_PF_HT * 8) { | |
75 gravity = LJ_PF_HT * 8; | |
76 } | |
77 | |
78 dst->rotation = rotation; | |
79 dst->movement = movement; | |
80 dst->gravity = gravity; | |
81 dst->other = other; | |
82 } | |
83 | |
84 static const LJFixed softDropSpeeds[3] = { | |
85 LJITOFIX(1), | |
86 LJITOFIX(1)/2, | |
87 LJITOFIX(1)/3 | |
88 }; | |
89 | |
90 void addKeysToInput(LJInput *dst, LJBits keys, const LJField *p, LJControl *c) { | |
91 int actualKeys = keys; | |
92 | |
93 if (c->replaySrc) { | |
94 keys = getReplayFrame(c->replaySrc, dst); | |
95 if (keys == LJREPLAY_EOF) { | |
96 keys = actualKeys; | |
97 replayClose(c->replaySrc); | |
98 c->replaySrc = NULL; | |
99 } | |
100 } | |
101 | |
102 int lastFrameKeys = c->lastKeys; | |
103 | |
104 // If diagonal presses are disabled, ignore any changes | |
105 if (!c->allowDiagonals | |
106 && (keys & (VKEY_UP | VKEY_DOWN)) | |
107 && (keys & (VKEY_LEFT | VKEY_RIGHT))) { | |
108 keys &= ~(VKEY_UP | VKEY_DOWN | VKEY_LEFT | VKEY_RIGHT); | |
109 keys |= lastFrameKeys | |
110 & (VKEY_UP | VKEY_DOWN | VKEY_LEFT | VKEY_RIGHT); | |
111 } | |
112 | |
113 LJBits newKeys = keys & ~lastFrameKeys; | |
114 c->lastKeys = keys; | |
115 | |
116 // Count presses for Baboo!, excluding console buttons | |
117 c->presses += countOnes(newKeys & 0x0000FFFF); | |
118 | |
119 // Only once the side effect of counting presses for Baboo! | |
120 // is complete can we break out of a replay. | |
121 if (c->replaySrc) { | |
122 return; | |
123 } | |
124 | |
125 LJBits releasedKeys = ~keys & lastFrameKeys; | |
126 | |
127 // At this point, c->lastKeys holds the keys actually held | |
128 // by the player this frame, and lastFrameKeys holds the keys | |
129 // actually held by the player last frame. | |
130 | |
131 // Handle keys that must be re-pressed | |
132 releasedKeys &= ~c->repressKeys; | |
133 c->repressKeys &= keys; | |
134 keys &= ~c->repressKeys; | |
135 | |
136 // If locking in a mode without ARE, require | |
137 // down to be re-pressed before next piece | |
138 if (p->sounds & LJSND_LOCK | |
139 && p->speed.entryDelay <= c->dasDelay) { | |
140 c->repressKeys |= VKEY_DOWN; | |
141 | |
142 // Treat up the same way when hard drop lock is set to lock on release. | |
143 if (c->hardDropLock != LJZANGI_SLIDE | |
144 || p->lockReset == LJLOCK_NOW | |
145 || p->speed.lockDelay <= c->dasDelay) { | |
146 c->repressKeys |= VKEY_UP | VKEY_MACRO(4); | |
147 } | |
148 } | |
149 | |
150 // Initial Rotation System (IRS): | |
151 // When a piece spawns from next or hold, and a rotation or macro | |
152 // key is held, treat the key as if they had just been pressed. | |
153 // Treat hard drop the same way when ARE is turned on. | |
154 if ((p->sounds & (LJSND_SPAWN | LJSND_HOLD)) | |
155 && c->initialRotate) { | |
156 newKeys |= c->lastKeys | |
157 & (VKEY_ROTL | VKEY_ROTR | VKEY_MACROS); | |
158 if (p->speed.entryDelay > 0) { | |
159 newKeys |= c->lastKeys | |
160 & VKEY_UP; | |
161 } | |
162 } | |
163 | |
164 // if we're pretending that keys are not pressed, | |
165 // pretend consistently | |
166 newKeys &= keys; | |
167 | |
168 // TGM does not perform sideways movement on | |
169 // the first frame after a piece is spawned. | |
170 if (c->initialDAS == 0 && | |
171 (p->sounds & (LJSND_SPAWN | LJSND_HOLD))) { | |
172 | |
173 } else if (keys & VKEY_LEFT) { | |
174 if (c->dasCounter > -(int)c->dasDelay) { | |
175 if (c->dasCounter >= 0) { | |
176 c->dasCounter = -1; | |
177 dst->movement = -1; | |
178 } else { | |
179 c->dasCounter -= 1; | |
180 } | |
181 } else { | |
182 int dasSpeed = c->dasSpeed; | |
183 if (dasSpeed) { | |
184 dst->movement = -1; | |
185 c->dasCounter += dasSpeed - 1; | |
186 } else { | |
187 dst->movement = -(int)LJ_PF_WID; | |
188 } | |
189 } | |
190 } else if (keys & VKEY_RIGHT) { | |
191 if (c->dasCounter < c->dasDelay) { | |
192 if (c->dasCounter <= 0) { | |
193 c->dasCounter = 1; | |
194 dst->movement = 1; | |
195 } else { | |
196 c->dasCounter += 1; | |
197 } | |
198 } else { | |
199 int dasSpeed = c->dasSpeed; | |
200 if (dasSpeed) { | |
201 dst->movement = 1; | |
202 c->dasCounter -= dasSpeed - 1; | |
203 } else { | |
204 dst->movement = (int)LJ_PF_WID; | |
205 } | |
206 } | |
207 } else { | |
208 c->dasCounter = 0; | |
209 } | |
210 | |
211 if(keys & VKEY_DOWN) { | |
212 int g = softDropSpeeds[c->softDropSpeed]; | |
213 | |
214 // dither speed to 1/8G units | |
215 g += ljitofix(p->gameTime % 3) / 24; | |
216 dst->gravity += g >> 13; | |
217 | |
218 if ((newKeys & VKEY_DOWN) | |
219 || c->softDropLock == LJZANGI_LOCK) { | |
220 dst->other |= LJI_LOCK; | |
221 } | |
222 } | |
223 | |
224 if (newKeys & VKEY_ROTL) { | |
225 dst->rotation -= 1; | |
226 } | |
227 if (newKeys & VKEY_ROTR) { | |
228 dst->rotation += 1; | |
229 } | |
230 if (newKeys & VKEY_HOLD) { | |
231 dst->other |= LJI_HOLD; | |
232 } | |
233 if (newKeys & VKEY_UP) { | |
234 dst->gravity = LJ_PF_HT << 3; | |
235 if (p->state == LJS_LANDED | |
236 || c->hardDropLock == LJZANGI_LOCK) { | |
237 dst->other |= LJI_LOCK; | |
238 } | |
239 } | |
240 | |
241 if (c->hardDropLock == LJZANGI_LOCK_RELEASE) { | |
242 if (releasedKeys & VKEY_UP) { | |
243 dst->other |= LJI_LOCK; | |
244 } | |
245 } | |
246 if (c->softDropLock == LJZANGI_LOCK_RELEASE) { | |
247 if (releasedKeys & VKEY_DOWN) { | |
248 dst->other |= LJI_LOCK; | |
249 } | |
250 } | |
251 | |
252 addMacrosToInput(dst, newKeys); | |
253 | |
254 // Baboo! ends with a hard drop | |
255 if (p->gimmick == LJGM_BABY && c->presses >= 300) { | |
256 dst->gravity = LJ_PF_HT << 3; | |
257 dst->other |= LJI_LOCK; | |
258 } | |
259 | |
260 if (c->replayDst) { | |
261 replayRecord(c->replayDst, actualKeys, dst); | |
262 } | |
263 } |