Mercurial > hg > index.fcgi > lj > lj046-2players
diff src/macro.c @ 0:c84446dfb3f5
initial add
author | paulo@localhost |
---|---|
date | Fri, 13 Mar 2009 00:39:12 -0700 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/macro.c Fri Mar 13 00:39:12 2009 -0700 1.3 @@ -0,0 +1,263 @@ 1.4 +/* Input handling for LOCKJAW Tetromino Game 1.5 + 1.6 +Copyright (C) 2006 Damian Yerrick <tepples+lj@spamcop.net> 1.7 + 1.8 +This work is free software; you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation; either version 2 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program; if not, write to the Free Software 1.20 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.21 + 1.22 +Original game concept and design by Alexey Pajitnov. 1.23 +The Software is not sponsored or endorsed by Alexey Pajitnov, Elorg, 1.24 +or The Tetris Company LLC. 1.25 + 1.26 +*/ 1.27 +#include "lj.h" 1.28 +#include "ljcontrol.h" 1.29 +#include "ljreplay.h" 1.30 +#include "pcjoy.h" 1.31 + 1.32 +// first is rotation (+1 = 90 deg clockwise) 1.33 +// second is movement (+1 = right 1 block) 1.34 +// third is gravity (+1 = down 1/8 block) 1.35 +// fourth is extra actions (hold, lock) 1.36 +LJInput macros[8] = { 1.37 + { -1, 0, 0, 0 }, // default: alt. rotate left 1.38 + { -2, 0, 0, 0 }, // default: rotate left twice 1.39 + { 0, -9, 0, 0 }, // default: far left 1.40 + { 0, 9, 0, 0 }, // default: far right 1.41 + { 0, 0, 20*8, 0 }, // default: firm drop 1.42 + { 0, 0, 0, LJI_HOLD }, // default: alternate hold 1.43 + { 0, 0, 0, 0 }, 1.44 + { 0, 0, 0, 0 } 1.45 +}; 1.46 + 1.47 +void addMacrosToInput(LJInput *dst, LJBits keys) { 1.48 + int rotation = dst->rotation; 1.49 + int movement = dst->movement; 1.50 + int gravity = dst->gravity; 1.51 + int other = dst->other; 1.52 + int macro; 1.53 + 1.54 + keys >>= 8; 1.55 + for (macro = 0; 1.56 + macro < 8; 1.57 + keys >>= 1, ++macro) { 1.58 + if (keys & 1) { 1.59 + rotation += macros[macro].rotation; 1.60 + movement += macros[macro].movement; 1.61 + gravity += macros[macro].gravity; 1.62 + other |= macros[macro].other; 1.63 + } 1.64 + } 1.65 + 1.66 + // Clip rotation to [-3, +3] 1.67 + rotation -= rotation / 4 * 4; 1.68 + 1.69 + // Clip movement to playfield width 1.70 + if (movement < (int)-LJ_PF_WID) { 1.71 + movement = -LJ_PF_WID; 1.72 + } else if (movement > (int)LJ_PF_WID) { 1.73 + movement = LJ_PF_WID; 1.74 + } 1.75 + 1.76 + // Clip gravity to playfield height 1.77 + if (gravity > LJ_PF_HT * 8) { 1.78 + gravity = LJ_PF_HT * 8; 1.79 + } 1.80 + 1.81 + dst->rotation = rotation; 1.82 + dst->movement = movement; 1.83 + dst->gravity = gravity; 1.84 + dst->other = other; 1.85 +} 1.86 + 1.87 +static const LJFixed softDropSpeeds[3] = { 1.88 + LJITOFIX(1), 1.89 + LJITOFIX(1)/2, 1.90 + LJITOFIX(1)/3 1.91 +}; 1.92 + 1.93 +void addKeysToInput(LJInput *dst, LJBits keys, const LJField *p, LJControl *c) { 1.94 + int actualKeys = keys; 1.95 + 1.96 + if (c->replaySrc) { 1.97 + keys = getReplayFrame(c->replaySrc, dst); 1.98 + if (keys == LJREPLAY_EOF) { 1.99 + keys = actualKeys; 1.100 + replayClose(c->replaySrc); 1.101 + c->replaySrc = NULL; 1.102 + } 1.103 + } 1.104 + 1.105 + int lastFrameKeys = c->lastKeys; 1.106 + 1.107 + // If diagonal presses are disabled, ignore any changes 1.108 + if (!c->allowDiagonals 1.109 + && (keys & (VKEY_UP | VKEY_DOWN)) 1.110 + && (keys & (VKEY_LEFT | VKEY_RIGHT))) { 1.111 + keys &= ~(VKEY_UP | VKEY_DOWN | VKEY_LEFT | VKEY_RIGHT); 1.112 + keys |= lastFrameKeys 1.113 + & (VKEY_UP | VKEY_DOWN | VKEY_LEFT | VKEY_RIGHT); 1.114 + } 1.115 + 1.116 + LJBits newKeys = keys & ~lastFrameKeys; 1.117 + c->lastKeys = keys; 1.118 + 1.119 + // Count presses for Baboo!, excluding console buttons 1.120 + c->presses += countOnes(newKeys & 0x0000FFFF); 1.121 + 1.122 + // Only once the side effect of counting presses for Baboo! 1.123 + // is complete can we break out of a replay. 1.124 + if (c->replaySrc) { 1.125 + return; 1.126 + } 1.127 + 1.128 + LJBits releasedKeys = ~keys & lastFrameKeys; 1.129 + 1.130 + // At this point, c->lastKeys holds the keys actually held 1.131 + // by the player this frame, and lastFrameKeys holds the keys 1.132 + // actually held by the player last frame. 1.133 + 1.134 + // Handle keys that must be re-pressed 1.135 + releasedKeys &= ~c->repressKeys; 1.136 + c->repressKeys &= keys; 1.137 + keys &= ~c->repressKeys; 1.138 + 1.139 + // If locking in a mode without ARE, require 1.140 + // down to be re-pressed before next piece 1.141 + if (p->sounds & LJSND_LOCK 1.142 + && p->speed.entryDelay <= c->dasDelay) { 1.143 + c->repressKeys |= VKEY_DOWN; 1.144 + 1.145 + // Treat up the same way when hard drop lock is set to lock on release. 1.146 + if (c->hardDropLock != LJZANGI_SLIDE 1.147 + || p->lockReset == LJLOCK_NOW 1.148 + || p->speed.lockDelay <= c->dasDelay) { 1.149 + c->repressKeys |= VKEY_UP | VKEY_MACRO(4); 1.150 + } 1.151 + } 1.152 + 1.153 + // Initial Rotation System (IRS): 1.154 + // When a piece spawns from next or hold, and a rotation or macro 1.155 + // key is held, treat the key as if they had just been pressed. 1.156 + // Treat hard drop the same way when ARE is turned on. 1.157 + if ((p->sounds & (LJSND_SPAWN | LJSND_HOLD)) 1.158 + && c->initialRotate) { 1.159 + newKeys |= c->lastKeys 1.160 + & (VKEY_ROTL | VKEY_ROTR | VKEY_MACROS); 1.161 + if (p->speed.entryDelay > 0) { 1.162 + newKeys |= c->lastKeys 1.163 + & VKEY_UP; 1.164 + } 1.165 + } 1.166 + 1.167 + // if we're pretending that keys are not pressed, 1.168 + // pretend consistently 1.169 + newKeys &= keys; 1.170 + 1.171 + // TGM does not perform sideways movement on 1.172 + // the first frame after a piece is spawned. 1.173 + if (c->initialDAS == 0 && 1.174 + (p->sounds & (LJSND_SPAWN | LJSND_HOLD))) { 1.175 + 1.176 + } else if (keys & VKEY_LEFT) { 1.177 + if (c->dasCounter > -(int)c->dasDelay) { 1.178 + if (c->dasCounter >= 0) { 1.179 + c->dasCounter = -1; 1.180 + dst->movement = -1; 1.181 + } else { 1.182 + c->dasCounter -= 1; 1.183 + } 1.184 + } else { 1.185 + int dasSpeed = c->dasSpeed; 1.186 + if (dasSpeed) { 1.187 + dst->movement = -1; 1.188 + c->dasCounter += dasSpeed - 1; 1.189 + } else { 1.190 + dst->movement = -(int)LJ_PF_WID; 1.191 + } 1.192 + } 1.193 + } else if (keys & VKEY_RIGHT) { 1.194 + if (c->dasCounter < c->dasDelay) { 1.195 + if (c->dasCounter <= 0) { 1.196 + c->dasCounter = 1; 1.197 + dst->movement = 1; 1.198 + } else { 1.199 + c->dasCounter += 1; 1.200 + } 1.201 + } else { 1.202 + int dasSpeed = c->dasSpeed; 1.203 + if (dasSpeed) { 1.204 + dst->movement = 1; 1.205 + c->dasCounter -= dasSpeed - 1; 1.206 + } else { 1.207 + dst->movement = (int)LJ_PF_WID; 1.208 + } 1.209 + } 1.210 + } else { 1.211 + c->dasCounter = 0; 1.212 + } 1.213 + 1.214 + if(keys & VKEY_DOWN) { 1.215 + int g = softDropSpeeds[c->softDropSpeed]; 1.216 + 1.217 + // dither speed to 1/8G units 1.218 + g += ljitofix(p->gameTime % 3) / 24; 1.219 + dst->gravity += g >> 13; 1.220 + 1.221 + if ((newKeys & VKEY_DOWN) 1.222 + || c->softDropLock == LJZANGI_LOCK) { 1.223 + dst->other |= LJI_LOCK; 1.224 + } 1.225 + } 1.226 + 1.227 + if (newKeys & VKEY_ROTL) { 1.228 + dst->rotation -= 1; 1.229 + } 1.230 + if (newKeys & VKEY_ROTR) { 1.231 + dst->rotation += 1; 1.232 + } 1.233 + if (newKeys & VKEY_HOLD) { 1.234 + dst->other |= LJI_HOLD; 1.235 + } 1.236 + if (newKeys & VKEY_UP) { 1.237 + dst->gravity = LJ_PF_HT << 3; 1.238 + if (p->state == LJS_LANDED 1.239 + || c->hardDropLock == LJZANGI_LOCK) { 1.240 + dst->other |= LJI_LOCK; 1.241 + } 1.242 + } 1.243 + 1.244 + if (c->hardDropLock == LJZANGI_LOCK_RELEASE) { 1.245 + if (releasedKeys & VKEY_UP) { 1.246 + dst->other |= LJI_LOCK; 1.247 + } 1.248 + } 1.249 + if (c->softDropLock == LJZANGI_LOCK_RELEASE) { 1.250 + if (releasedKeys & VKEY_DOWN) { 1.251 + dst->other |= LJI_LOCK; 1.252 + } 1.253 + } 1.254 + 1.255 + addMacrosToInput(dst, newKeys); 1.256 + 1.257 + // Baboo! ends with a hard drop 1.258 + if (p->gimmick == LJGM_BABY && c->presses >= 300) { 1.259 + dst->gravity = LJ_PF_HT << 3; 1.260 + dst->other |= LJI_LOCK; 1.261 + } 1.262 + 1.263 + if (c->replayDst) { 1.264 + replayRecord(c->replayDst, actualKeys, dst); 1.265 + } 1.266 +}