/* bomb - automatic interactive visual stimulation Copyright (C) 1994 Scott Draves 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 2 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, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #define SHOW_DRIVER 0 void step_rule_rug_multi(int frame, rule_t *p, image8_t *fb) { int x, y; board_t *s_heat_board, *d_heat_board; board_t *s_game_board, *d_game_board; u_char *lp0, *lp1; static int ptab[] = {1, 2, 4, 5}; int nplanes = ptab[iclamp(p->brain_shift, 4)]; int stripe_height = SMALL_YSIZE / nplanes; static int phase = 0; int slowdown = nplanes * p->driver_slowdown; if (++phase >= nplanes) phase = 0; dbuf = frame&1; s_heat_board=&board[dbuf]; d_heat_board=&board[1-dbuf]; dbuf = (frame/slowdown)&1; s_game_board=&board2[dbuf]; d_game_board=&board2[1-dbuf]; for(y=0;y<=SMALL_YSIZE+1;y++) { (*s_game_board)[0][y] = (*s_game_board)[SMALL_XSIZE][y]; (*s_game_board)[SMALL_XSIZE+1][y] = (*s_game_board)[1][y]; (*s_heat_board)[0][y] = (*s_heat_board)[SMALL_XSIZE][y]; (*s_heat_board)[SMALL_XSIZE+1][y] = (*s_heat_board)[1][y]; } for(x=0;x<=SMALL_XSIZE+1;x++) { (*s_game_board)[x][0] = (*s_game_board)[x][SMALL_YSIZE]; (*s_game_board)[x][SMALL_YSIZE+1] = (*s_game_board)[x][1]; (*s_heat_board)[x][0] = (*s_heat_board)[x][SMALL_YSIZE]; (*s_heat_board)[x][SMALL_YSIZE+1] = (*s_heat_board)[x][1]; } if (0 == ((frame+1) % slowdown)) for (y = 1; y<=SMALL_YSIZE; y++) { for (x=1; x<=SMALL_XSIZE; x++) { int ht = (((*s_game_board)[x ][y ]) + (*s_game_board)[x+1][y ] + (*s_game_board)[x-1][y ] + (*s_game_board)[x ][y+1] + (*s_game_board)[x ][y-1])/5; (*d_game_board)[x][y] = (ht - 1) & 471; } } for (y=1; y<=SMALL_YSIZE; y++) { lp0 = fb->p + (fb->stride * (y - 1)); lp1 = lp0 + fb->stride * SMALL_YSIZE; for (x=1; x<=SMALL_XSIZE; x++) { int heat, dh; int driver, hn, hs, he, hw, hc, denom; int gy; driver = 0; for (gy = 1 + ((y-1)/nplanes); gy <= SMALL_YSIZE; gy += stripe_height) { int v; v = (*s_game_board)[x][gy]; driver = ((driver<<1) | (v < 20)); } hn = (*s_heat_board)[x ][y-1]; hs = (*s_heat_board)[x ][y+1]; he = (*s_heat_board)[x+1][y ]; hw = (*s_heat_board)[x-1][y ]; hc = (*s_heat_board)[x ][y ]; denom = 5; heat = hn + hs + he + hw + hc; dh = p->speed; if (driver&0x1) { heat -= hn; denom--;} if (driver&0x2) { heat -= hs; denom--;} if (driver&0x4) { heat -= he; denom--;} if (driver&0x8) { heat -= hw; denom--;} heat = ((heat / denom) + dh) & p->mask; (*d_heat_board)[x][y] = heat; #if SHOW_DRIVER p1 = iclamp(p1, 2 + nplanes); switch (p1) { case 0: // if (p->remap) heat = remap[heat]; break; case 1: heat = driver ^ (driver >> 8) ^ (driver >> 16); break; default: heat = (driver & (1 << (p1 - 2))) ? 0 : 100; break; } #else // if (p->remap) heat = remap[heat]; #endif lp0[SMALL_XSIZE] = heat; *lp0++ = heat; lp1[SMALL_XSIZE] = heat; *lp1++ = heat; } } }