void Fire::Process() { auto enm = GetMap()->GetEnemyHolder()->GetNearest(this->pixel_x(), this->pixel_y(), 7, [this](Enemy* e) /*I AM KING OF SPACES*/ { return !e->IsRocketFriend() && e != this; }); ++length_; if (enm != nullptr) { ProcessSpeed(enm->pixel_x(), enm->pixel_y(), 1); if ((abs(enm->pixel_x() - pixel_x()) + abs(enm->pixel_y() - pixel_y())) < 48) { enm->Hit(1); } } ProcessMove(); state_w_ = (length_ / 5) % 6; if (length_ > 30) GetMap()->GetEnemyHolder()->AddToDelete(this); }
static void draw_hoshi (unsigned short pos) { /* color and drawmode are already set before this function (all lines and hoshi and stuff are drawn together) */ if (!on_board(pos)) { return; } if ((unsigned) I (pos) < MIN_X || (unsigned) I (pos) >= MAX_X || (unsigned) J (pos) < MIN_Y || (unsigned) J (pos) >= MAX_Y) { return; } if (intersection_size > 8) { rb->lcd_fillrect (pixel_x (pos) + LINE_OFFSET - 1, pixel_y (pos) + LINE_OFFSET - 1, 3, 3); } else { rb->lcd_drawpixel (pixel_x (pos) + LINE_OFFSET - 1, pixel_y (pos) + LINE_OFFSET - 1); rb->lcd_drawpixel (pixel_x (pos) + LINE_OFFSET + 1, pixel_y (pos) + LINE_OFFSET + 1); } }
void TransformState::getProjMatrix(mat4& projMatrix) const { double halfFov = std::atan(0.5 / getAltitude()); double topHalfSurfaceDistance = std::sin(halfFov) * getAltitude() / std::sin(M_PI / 2.0f - getPitch() - halfFov); // Calculate z value of the farthest fragment that should be rendered. double farZ = std::cos(M_PI / 2.0f - getPitch()) * topHalfSurfaceDistance + getAltitude(); matrix::perspective(projMatrix, 2.0f * std::atan((size.height / 2.0f) / getAltitude()), double(size.width) / size.height, 0.1, farZ); matrix::translate(projMatrix, projMatrix, 0, 0, -getAltitude()); // After the rotateX, z values are in pixel units. Convert them to // altitude unites. 1 altitude unit = the screen height. const bool flippedY = viewportMode == ViewportMode::FlippedY; matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1, 1.0f / (rotatedNorth() ? size.width : size.height)); using NO = NorthOrientation; switch (getNorthOrientation()) { case NO::Rightwards: matrix::rotate_y(projMatrix, projMatrix, getPitch()); break; case NO::Downwards: matrix::rotate_x(projMatrix, projMatrix, -getPitch()); break; case NO::Leftwards: matrix::rotate_y(projMatrix, projMatrix, -getPitch()); break; default: matrix::rotate_x(projMatrix, projMatrix, getPitch()); break; } matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle()); matrix::translate(projMatrix, projMatrix, pixel_x() - size.width / 2.0f, pixel_y() - size.height / 2.0f, 0); }
void Enemy::ProcessSpeed(int pixel_x_to, int pixel_y_to, int force) { pixel_x_to += 16; pixel_y_to += 16; //auto obj = GetMap()->GetNearest(pixel_x(), pixel_y()); int diff_x = pixel_x_to - pixel_x(); int diff_y = pixel_y_to - pixel_y(); float radius = sqrt(static_cast<float>(diff_x * diff_x + diff_y * diff_y)); if (radius != 0) { speed_.x += static_cast<int>((force) * (1.0f * diff_x / radius)); speed_.y += static_cast<int>((force) * (1.0f * diff_y / radius)); } if (speed_.x > 0) speed_.x = std::min(speed_.x, 5); else speed_.x = std::max(speed_.x, -5); if (speed_.y > 0) speed_.y = std::min(speed_.y, 5); else speed_.y = std::max(speed_.y, -5); }
void Enemy::Process() { auto obj = GetMap()->GetNearest(pixel_x(), pixel_y()); if (obj != nullptr) ProcessSpeed(obj->posx() * 32, obj->posy() * 32); ProcessMove(); ProcessHealth(); }
void Enemy::ProcessHealth() { if (health_ < 0) { GetMap()->GetEnemyHolder()->AddToDelete(this); getEffectOf<RedBlood>()->SetPos(pixel_x(), pixel_y(), angle())->Start(); } }
static void draw_stone (unsigned short pos, bool black) { if (!on_board (pos)) { return; } draw_stone_raw (pixel_x (pos), pixel_y (pos), black); }
void Ork::Process() { Enemy::Process(); int posx = pixel_x() / 32; int posy = pixel_y() / 32; auto n = (*GetMap())[posx][posy]; if (n != nullptr && n->IsLine()) { n->Hit(1); } }
void Jew::Process() { Enemy::Process(); bool is_near = false; GetMap()->ForEach([&](Object* object) { if (object == nullptr) return; if (object->IsLine()) is_near = true; }, pixel_x() / 32, pixel_y() / 32, 1); if (is_near) GetPlayer()->ChangeStone(-1); }
static void draw_cursor (unsigned short pos) { if (!on_board (pos)) { return; } #if LCD_DEPTH > 1 rb->lcd_set_foreground (CURSOR_COLOR); #else rb->lcd_set_drawmode (DRMODE_COMPLEMENT); #endif rb->lcd_drawrect (pixel_x (pos), pixel_y (pos), intersection_size, intersection_size); rb->lcd_set_drawmode (DRMODE_SOLID); }
void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ) const { if (size.isEmpty()) { return; } // Find the distance from the center point [width/2, height/2] to the // center top point [width/2, 0] in Z units, using the law of sines. // 1 Z unit is equivalent to 1 horizontal px at the center of the map // (the distance between[width/2, height/2] and [width/2 + 1, height/2]) const double halfFov = getFieldOfView() / 2.0; const double groundAngle = M_PI / 2.0 + getPitch(); const double topHalfSurfaceDistance = std::sin(halfFov) * getCameraToCenterDistance() / std::sin(M_PI - groundAngle - halfFov); // Calculate z distance of the farthest fragment that should be rendered. const double furthestDistance = std::cos(M_PI / 2 - getPitch()) * topHalfSurfaceDistance + getCameraToCenterDistance(); // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` const double farZ = furthestDistance * 1.01; matrix::perspective(projMatrix, getFieldOfView(), double(size.width) / size.height, nearZ, farZ); const bool flippedY = viewportMode == ViewportMode::FlippedY; matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1, 1); matrix::translate(projMatrix, projMatrix, 0, 0, -getCameraToCenterDistance()); using NO = NorthOrientation; switch (getNorthOrientation()) { case NO::Rightwards: matrix::rotate_y(projMatrix, projMatrix, getPitch()); break; case NO::Downwards: matrix::rotate_x(projMatrix, projMatrix, -getPitch()); break; case NO::Leftwards: matrix::rotate_y(projMatrix, projMatrix, -getPitch()); break; default: matrix::rotate_x(projMatrix, projMatrix, getPitch()); break; } matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle()); matrix::translate(projMatrix, projMatrix, pixel_x() - size.width / 2.0f, pixel_y() - size.height / 2.0f, 0); matrix::scale(projMatrix, projMatrix, 1, 1, 1.0 / Projection::getMetersPerPixelAtLatitude(getLatLng(LatLng::Unwrapped).latitude(), getZoom())); }
void Rocket::Process() { auto enm = GetMap()->GetEnemyHolder()->GetNearest(this->pixel_x(), this->pixel_y(), 7, [this](Enemy* e) /*I AM KING OF SPACES*/ { return !e->IsRocketFriend() && e != this; }); ++length_; if (enm != nullptr) { speed_.x += rand() % 2 - 1; speed_.y += rand() % 2 - 1; ProcessSpeed(enm->pixel_x(), enm->pixel_y(), 2); if ((abs(enm->pixel_x() - pixel_x()) + abs(enm->pixel_y() - pixel_y())) < 48) { GetMap()->GetEnemyHolder()->AddToDelete(this); getEffectOf<Explosion>()->SetPos(pixel_x(), pixel_y(), angle())->Start(); GetMap()->GetEnemyHolder()->ForEach([](Enemy* enm) { enm->Hit(11); }, pixel_x(), pixel_y(), 64 * 64); } } ProcessMove(); state_w_ = (length_ / 2) % 4; if (length_ > 80) { GetMap()->GetEnemyHolder()->AddToDelete(this); getEffectOf<Explosion>()->SetPos(pixel_x(), pixel_y(), angle())->Start(); } }
void TransformState::getProjMatrix(mat4& projMatrix, uint16_t nearZ, bool aligned) const { if (size.isEmpty()) { return; } // Find the distance from the center point [width/2, height/2] to the // center top point [width/2, 0] in Z units, using the law of sines. // 1 Z unit is equivalent to 1 horizontal px at the center of the map // (the distance between[width/2, height/2] and [width/2 + 1, height/2]) const double halfFov = getFieldOfView() / 2.0; const double groundAngle = M_PI / 2.0 + getPitch(); const double topHalfSurfaceDistance = std::sin(halfFov) * getCameraToCenterDistance() / std::sin(M_PI - groundAngle - halfFov); // Calculate z distance of the farthest fragment that should be rendered. const double furthestDistance = std::cos(M_PI / 2 - getPitch()) * topHalfSurfaceDistance + getCameraToCenterDistance(); // Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance` const double farZ = furthestDistance * 1.01; matrix::perspective(projMatrix, getFieldOfView(), double(size.width) / size.height, nearZ, farZ); const bool flippedY = viewportMode == ViewportMode::FlippedY; matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1, 1); matrix::translate(projMatrix, projMatrix, 0, 0, -getCameraToCenterDistance()); using NO = NorthOrientation; switch (getNorthOrientation()) { case NO::Rightwards: matrix::rotate_y(projMatrix, projMatrix, getPitch()); break; case NO::Downwards: matrix::rotate_x(projMatrix, projMatrix, -getPitch()); break; case NO::Leftwards: matrix::rotate_y(projMatrix, projMatrix, -getPitch()); break; default: matrix::rotate_x(projMatrix, projMatrix, getPitch()); break; } matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle()); const double dx = pixel_x() - size.width / 2.0f, dy = pixel_y() - size.height / 2.0f; matrix::translate(projMatrix, projMatrix, dx, dy, 0); if (axonometric) { // mat[11] controls perspective projMatrix[11] = 0; // mat[8], mat[9] control x-skew, y-skew projMatrix[8] = xSkew; projMatrix[9] = ySkew; } matrix::scale(projMatrix, projMatrix, 1, 1, 1.0 / Projection::getMetersPerPixelAtLatitude(getLatLng(LatLng::Unwrapped).latitude(), getZoom())); // Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles. // We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional // coordinates. Additionally, we adjust by half a pixel in either direction in case that viewport dimension // is an odd integer to preserve rendering to the pixel grid. We're rotating this shift based on the angle // of the transformation so that 0°, 90°, 180°, and 270° rasters are crisp, and adjust the shift so that // it is always <= 0.5 pixels. if (aligned) { const float xShift = float(size.width % 2) / 2, yShift = float(size.height % 2) / 2; const double angleCos = std::cos(angle), angleSin = std::sin(angle); double devNull; const float dxa = -std::modf(dx, &devNull) + angleCos * xShift + angleSin * yShift; const float dya = -std::modf(dy, &devNull) + angleCos * yShift + angleSin * xShift; matrix::translate(projMatrix, projMatrix, dxa > 0.5 ? dxa - 1 : dxa, dya > 0.5 ? dya - 1 : dya, 0); } }
void draw_screen_display (void) { #if LCD_DEPTH > 1 int saved_fg = rb->lcd_get_foreground (); int saved_bg = rb->lcd_get_background (); #endif int saved_drmode = rb->lcd_get_drawmode (); if (cursor_pos != last_cursor_pos || intersection_size != last_int_size) { cursor_updated (); } #if LCD_DEPTH > 1 rb->lcd_set_backdrop (NULL); rb->lcd_set_foreground (BOARD_COLOR); rb->lcd_set_background (BACKGROUND_COLOR); rb->lcd_set_drawmode (DRMODE_SOLID); #else rb->lcd_set_drawmode (DRMODE_SOLID + DRMODE_INVERSEVID); #endif rb->lcd_clear_display (); rb->lcd_fillrect (pixel_x (POS (MIN_X, MIN_Y)), pixel_y (POS (MIN_X, MIN_Y)), (MAX_X - MIN_X) * intersection_size, (MAX_Y - MIN_Y) * intersection_size); #if LCD_DEPTH > 1 rb->lcd_set_foreground (LINE_COLOR); #else rb->lcd_set_drawmode (DRMODE_SOLID); #endif unsigned int i; for (i = MIN_Y; i < MAX_Y; ++i) { rb->lcd_hline (pixel_x (POS (MIN_X, i)) + LINE_OFFSET + extend_l, pixel_x (POS (MAX_X - 1, i)) + LINE_OFFSET + extend_r, pixel_y (POS (MIN_X, i)) + LINE_OFFSET); } for (i = MIN_X; i < MAX_X; ++i) { rb->lcd_vline (pixel_x (POS (i, MIN_Y)) + LINE_OFFSET, pixel_y (POS (i, MIN_Y)) + LINE_OFFSET + extend_t, pixel_y (POS (i, MAX_Y - 1)) + LINE_OFFSET + extend_b); } draw_all_hoshi (); draw_all_stones (); draw_cursor (cursor_pos); if (draw_variations) { mark_child_variations_sgf (); } draw_all_marks (); draw_footer (); rb->lcd_update (); #if LCD_DEPTH > 1 rb->lcd_set_foreground (saved_fg); rb->lcd_set_background (saved_bg); #endif rb->lcd_set_drawmode (saved_drmode); }
static void draw_all_marks (void) { unsigned int x, y; for (x = MIN_X; x < MAX_X; ++x) { for (y = MIN_Y; y < MAX_Y; ++y) { if (display_marks[x + y * board_width] != ' ') { #if LCD_DEPTH > 1 if (display_marks[x + y * board_width] != 'b' && display_marks[x + y * board_width] != 'w') { rb->lcd_set_foreground (MARK_COLOR); } else { rb->lcd_set_foreground (CURSOR_COLOR); } rb->lcd_set_drawmode (DRMODE_FG); #else rb->lcd_set_drawmode (DRMODE_FG + DRMODE_COMPLEMENT); #endif if (display_marks[x + y * board_width] & (1 << 7)) { char to_display[2]; int width, height; to_display[0] = display_marks[x + y * board_width] & (~(1 << 7)); to_display[1] = '\0'; rb->lcd_getstringsize (to_display, &width, &height); int display_x = pixel_x (POS (x, y)) + LINE_OFFSET - (width / 2); int display_y = pixel_y (POS (x, y)) + LINE_OFFSET - (height / 2); if (display_x < 0) { display_x = 0; } if (display_y < 0) { display_y = 0; } if (display_x + width >= LCD_WIDTH) { display_x = LCD_WIDTH - 1 - width; } if (display_y + height >= LCD_HEIGHT) { display_y = LCD_HEIGHT - 1 - height; } rb->lcd_putsxy (display_x, display_y, to_display); continue; } switch (display_marks[x + y * board_width]) { /* moves, 'mark', 'square' */ case 'b': case 'w': if (intersection_size <= 5) { DEBUGF ("screen is too small to mark current move\n"); break; } case 'm': if (intersection_size <= 5) { rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET + 1, pixel_y (POS (x, y)) + LINE_OFFSET + 1); rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET - 1, pixel_y (POS (x, y)) + LINE_OFFSET - 1); } else { rb->lcd_drawrect (pixel_x (POS (x, y)) + LINE_OFFSET - intersection_size / 6, pixel_y (POS (x, y)) + LINE_OFFSET - intersection_size / 6, (intersection_size / 6) * 2 + 1, (intersection_size / 6) * 2 + 1); } break; case 's': if (intersection_size <= 5) { rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET + 1, pixel_y (POS (x, y)) + LINE_OFFSET + 1); rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET - 1, pixel_y (POS (x, y)) + LINE_OFFSET - 1); } else { rb->lcd_fillrect (pixel_x (POS (x, y)) + LINE_OFFSET - intersection_size / 6, pixel_y (POS (x, y)) + LINE_OFFSET - intersection_size / 6, (intersection_size / 6) * 2 + 1, (intersection_size / 6) * 2 + 1); } break; case 'c': if (intersection_size > 7) { draw_circle (pixel_x (POS (x, y)) + LINE_OFFSET, pixel_y (POS (x, y)) + LINE_OFFSET, (intersection_size - 1) / 4, true); break; } /* purposely don't break here, draw small the same as a triangle */ case 't': if (intersection_size <= 7) { rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET - 1, pixel_y (POS (x, y)) + LINE_OFFSET + 1); rb->lcd_drawpixel (pixel_x (POS (x, y)) + LINE_OFFSET + 1, pixel_y (POS (x, y)) + LINE_OFFSET - 1); } else { xlcd_filltriangle (pixel_x (POS (x, y)) + LINE_OFFSET, pixel_y (POS (x, y)) + LINE_OFFSET - intersection_size / 4, pixel_x (POS (x, y)) + LINE_OFFSET + intersection_size / 4, pixel_y (POS (x, y)) + LINE_OFFSET + intersection_size / 4, pixel_x (POS (x, y)) + LINE_OFFSET - intersection_size / 4, pixel_y (POS (x, y)) + LINE_OFFSET + intersection_size / 4); } break; default: DEBUGF ("tried to display unknown mark '%c' %d\n", display_marks[x + y * board_width], display_marks[x + y * board_width]); break; }; rb->lcd_set_drawmode (DRMODE_SOLID); /* don't have to undo the colors for LCD_DEPTH > 1, most functions assume bg and fg get clobbered */ } } } }