void PinballMovement::bounce(bool collision) { add_x = add_y = 0.0; if (!collision) { x_speed = -x_speed; y_speed = -y_speed; return; } push_out(); float angle = get_pinball_angle(x_speed, y_speed); float dist = get_length(x_speed, y_speed); float found_a = -1.0f; for (float a = 0.0f; a < (2.0f*CHOW_PI); a += (2.0f*CHOW_PI) / 32.0f) { float x_move = 10.0f * cos(angle + a); float y_move = -10.0f * sin(angle + a); if (!test_offset(x_move, y_move)) { found_a = a; break; } } if (found_a == -1.0f) { x_speed = -x_speed; y_speed = -y_speed; return; } angle += found_a * 2.0f; if (angle > 2.0 * CHOW_PI) angle -= 2.0 * CHOW_PI; // add some randomness angle += randrange(-0.3f, 0.3f); dist += randrange(0.0f, 15.0f); x_speed = dist * cos(angle); y_speed = -dist * sin(angle); }
bool Movement::fix_position() { if (push_out()) return true; int table_index = (instance->direction/4) * 16; for (int i = 0; i < 8; i++) { int x = instance->x + fix_pos_table[table_index]*2; int y = instance->y + fix_pos_table[table_index+1]*2; table_index += 2; if (test_position(x, y)) continue; instance->set_position(x, y); return true; } instance->set_position(old_x, old_y); return false; }
void BallMovement::bounce(bool collision) { if (stop_speed != 0) return; #ifdef CHOWDREN_IS_AVGN fix_position(); int direction = instance->direction; float angle = rad(direction * 11.25f); float found_a = -1.0f; for (float a = 0.0f; a < (CHOW_PI*2.0f); a += (CHOW_PI*2.0f) / 16.0f) { float x_move = 10.0f * cos(angle + a); float y_move = -10.0f * sin(angle + a); int x = instance->x + x_move; int y = instance->y + y_move; if (!test_position(x, y)) { found_a = a; break; } } if (found_a == -1.0f) { instance->set_direction((instance->direction + 16) % 32, false); return; } angle += found_a * 2.0f; if (angle > 2.0 * CHOW_PI) angle -= 2.0 * CHOW_PI; instance->set_direction(deg(angle) / 11.25f, false); if (back_col) instance->flags &= ~REPEAT_BACK_COLLISION; else instance->collision_flags = 0; #else add_x = add_y = 0; if (collision) { if (back_col) has_back_col = true; push_out(); } int x = instance->x; int y = instance->y; x -= 8; y -= 8; int rebond = 0; if (test_position(x, y)) rebond |= 0x01; x += 16; if (test_position(x, y)) rebond |= 0x02; y += 16; if (test_position(x, y)) rebond |= 0x04; x -= 16; if (test_position(x, y)) rebond |= 0x08; int value = rebond_list[rebond * 32 + instance->direction]; if (test_direction(value, 8)) { int angles = 4; int angles2 = angles; bool is_free = false; while (true) { value -= angles; value &= 31; if (!test_direction(value, 8)) { is_free = true; break; } value += 2 * angles; value &= 31; if (!test_direction(value, 8)) { is_free = true; break; } value -= angles; value &= 31; angles += angles2; if (angles <= 16) break; } if (!is_free) value = randrange(32); } int rnd = randrange(100); if (rnd < randomizer) { rnd >>= 2; if (rnd < 25) { rnd -= 12; rnd &= 31; if (!test_direction(rnd, 8)) value = rnd; } }
int main(void) { uint8_t buf[1 << 16], *out; uint8_t state = 0; unsigned i, j, type = 0x20; struct { uint8_t buf[256]; unsigned pos; } psbuf[2], *cps = NULL; for (;;) { ssize_t got = read(0, (out = buf), sizeof(buf)); if (got < 0) die("Read error: %m"); if (got == 0) break; for (i = 0; i < (unsigned) got; i++) { switch (state) { case 0x57: /* 0x00000001 */ type = buf[i] & 0x1F; switch (type) { case NUT_SPS: case NUT_PPS: /* if we have PPS/SPS record it in the appropriate buffer */ cps = &psbuf[type == NUT_SPS ? 0 : 1 ]; cps->pos = 0; break; case NUT_CODED_SLICE_IDR: /* If we have an IDR (key) frame push the stored SPS/PPS out in front of it */ if (!cps) { got -= push_out(&out, &buf[i] - out); for (j = 0; j < 2; j++) put_out(psbuf[j].buf, psbuf[j].pos); } default: /* Anything other than SPS/PPS: stop recording */ cps = NULL; break; } break; } /* state of last four bytes packed into one byte; two bits for unseen/zero/over * one/one (0..3 respectively). */ state = (state << 2) | (buf[i] == 0x00 ? 1 : buf[i] == 0x01 ? 3 : 2); if (cps) { if (cps->pos == sizeof(cps->buf)) { fprintf(stderr, "Warning: SPS/PPS overrun!\n"); /* discard and forget about it. SPS/PPS are quite small - * if this buffer fills it's more likely that we're being * given something other than h264 than that the SPS or PPS is * that large. */ cps->pos = 0; cps = NULL; } cps->buf[cps->pos++] = buf[i]; } } /* push whatever is left at the end */ push_out(&out, got); } return 0; }