KaboHaze::KaboHaze(SpaceLocation *creator, Ship *ohost, double obasepower) : SpaceLocation(creator, Vector2(0.0, 0.0), 0.0) { STACKTRACE; prev = 0; next = 0; // update the list (insert at the start) if (KaboHazeFirst) KaboHazeFirst->prev = this; next = KaboHazeFirst; prev = 0; KaboHazeFirst = this; //mother = omother; host = ohost; basepower = obasepower; power = basepower; // decay_time = odecaytime; // in milliseconds newcrew = iround(host->getCrew()); oldcrew = newcrew; // this "haze" is passive, of course: collide_flag_anyone = 0; collide_flag_sameteam = 0; collide_flag_sameship = 0; // I'll make 64 rotated versions in total, if needed, which I'll store // in memory: for ( int i = 0; i < 64; ++i ) { shield_bmp[i] = 0; } sprite_index = 0; // no rotation. shield_sprite_index = 0; // this item cannot collide collide_flag_anyone = 0; // this is probably important ... otherwise a thing like a flipping wedge indicator // can avoid a shield from being drawn ?!?! layer = LAYER_SHIPS; set_depth(DEPTH_SHIPS + 0.1); // The +0.1 places this presence at a higher level, so that this routine is // always done after the ship was drawn! Thnx Orz, for telling. // Graphics init stuff for the shield ! // copy the ship sprite (yes, a COPY because we need to do some operations on it !) SpaceSprite *ship_spr; ship_spr = host->get_sprite(); if (!ship_spr) { state = 0; return; } //BITMAP *ship_bmp; int wship = ship_spr->width(); int hship = ship_spr->height(); BITMAP *ship_bmp = create_bitmap(wship, hship); clear_to_color(ship_bmp, 0); // important otherwise it contains artefacts int index = 0; ship_spr->draw(Vector2(0, 0), Vector2(wship, hship), index, ship_bmp); // this does a (masked?) blit // create a blurred image from this: int R = 3; blit_blur(ship_bmp, R); // a complex and costly funtion ! Inefficiently programmed as well of course (by me). // now, create a masked shield - only the area that covers the // blurred image of the ship: shield_bmp[sprite_index] = create_bitmap(wship, hship); // important otherwise it contains artefacts clear_to_color(shield_bmp[sprite_index], 0); // scale/draw a shield: /* // the raw shield image BITMAP *raw_bmp = this->sprite->get_bitmap_readonly(0); int wraw = raw_bmp->w; int hraw = raw_bmp->h; stretch_blit(raw_bmp, shield_bmp[sprite_index], 0, 0, wraw, hraw, 0, 0, wship, hship ); */ // a uniform green glow clear_to_color(shield_bmp[sprite_index], tw_makecol(0,255,0)); // mask out the areas outside the ship, so that the shield only covers // the ship. blit_singlecolor(ship_bmp, shield_bmp[sprite_index], tw_makecol(0,0,0)); destroy_bitmap(ship_bmp); // ok ! this is what we need - only things left are // resize // rotate // trans-draw. // which we've to do repeatedly. // we may also cache the rotated images ! // flashes can occur within the edges of the shield ... check where the // edges are !! (assuming here, it's a closed shape). edge_left = new int [hship]; edge_right = new int [hship]; for ( int j = 0; j < hship; ++j ) { edge_left[j] = -1; edge_right[j] = -1; for ( int i = 0; i < wship; ++i ) { int color = getpixel(shield_bmp[0], i, j); if ( color != 0 ) { if ( edge_left[j] == -1 ) edge_left[j] = i; edge_right[j] = i; } } } attributes &= ~ATTRIB_STANDARD_INDEX; }
static int process_blit(struct mdp_info *mdp, struct mdp_blit_req *req, struct file *src_file, unsigned long src_start, unsigned long src_len, struct file *dst_file, unsigned long dst_start, unsigned long dst_len) { struct ppp_regs regs = {0}; uint32_t luma_base; #if PPP_DUMP_BLITS mdp_dump_blit(req); #endif if (unlikely(req->src.format >= MDP_IMGTYPE_LIMIT || req->dst.format >= MDP_IMGTYPE_LIMIT)) { printk(KERN_ERR "mdp_ppp: img is of wrong format\n"); return -EINVAL; } if (unlikely(req->src_rect.x > req->src.width || req->src_rect.y > req->src.height || req->dst_rect.x > req->dst.width || req->dst_rect.y > req->dst.height)) { printk(KERN_ERR "mdp_ppp: img rect is outside of img!\n"); return -EINVAL; } if (unlikely(req->src_rect.x + req->src_rect.w > req->src.width || req->src_rect.y + req->src_rect.h > req->src.height || req->dst_rect.x + req->dst_rect.w > req->dst.width || req->dst_rect.y + req->dst_rect.h > req->dst.height)) { printk(KERN_ERR "mdp_ppp: img rect extends outside of img!\n"); return -EINVAL; } /* set the src image configuration */ regs.src_cfg = src_img_cfg[req->src.format]; regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0; regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0; regs.src_pack = pack_pattern[req->src.format]; /* set the dest image configuration */ regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI; regs.dst_pack = pack_pattern[req->dst.format]; /* set src, bpp, start pixel and ystride */ regs.src_bpp = mdp_get_bytes_per_pixel(req->src.format); luma_base = src_start + req->src.offset; regs.src0 = luma_base + get_luma_offset(&req->src, &req->src_rect, regs.src_bpp); regs.src1 = get_chroma_base(&req->src, luma_base, regs.src_bpp); regs.src1 += get_chroma_offset(&req->src, &req->src_rect, regs.src_bpp); regs.src_ystride = req->src.width * regs.src_bpp; set_src_region(&req->src, &req->src_rect, ®s); /* set dst, bpp, start pixel and ystride */ regs.dst_bpp = mdp_get_bytes_per_pixel(req->dst.format); luma_base = dst_start + req->dst.offset; regs.dst0 = luma_base + get_luma_offset(&req->dst, &req->dst_rect, regs.dst_bpp); regs.dst1 = get_chroma_base(&req->dst, luma_base, regs.dst_bpp); regs.dst1 += get_chroma_offset(&req->dst, &req->dst_rect, regs.dst_bpp); regs.dst_ystride = req->dst.width * regs.dst_bpp; set_dst_region(&req->dst_rect, ®s); if (!valid_src_dst(src_start, src_len, dst_start, dst_len, req, ®s)) { printk(KERN_ERR "mdp_ppp: final src or dst location is " "invalid, are you trying to make an image too large " "or to place it outside the screen?\n"); return -EINVAL; } /* set up operation register */ regs.op = 0; blit_rotate(req, ®s); blit_convert(req, ®s); if (req->flags & MDP_DITHER) regs.op |= PPP_OP_DITHER_EN; blit_blend(req, ®s); if (blit_scale(mdp, req, ®s)) { printk(KERN_ERR "mdp_ppp: error computing scale for img.\n"); return -EINVAL; } blit_blur(mdp, req, ®s); regs.op |= dst_op_chroma[req->dst.format] | src_op_chroma[req->src.format]; /* if the image is YCRYCB, the x and w must be even */ if (unlikely(req->src.format == MDP_YCRYCB_H2V1)) { req->src_rect.x = req->src_rect.x & (~0x1); req->src_rect.w = req->src_rect.w & (~0x1); req->dst_rect.x = req->dst_rect.x & (~0x1); req->dst_rect.w = req->dst_rect.w & (~0x1); } if (mdp_ppp_cfg_edge_cond(req, ®s)) return -EINVAL; /* for simplicity, always write the chroma stride */ regs.src_ystride &= 0x3fff; regs.src_ystride |= regs.src_ystride << 16; regs.dst_ystride &= 0x3fff; regs.dst_ystride |= regs.dst_ystride << 16; regs.bg_ystride &= 0x3fff; regs.bg_ystride |= regs.bg_ystride << 16; #if PPP_DUMP_BLITS pr_info("%s: sending blit\n", __func__); #endif send_blit(mdp, req, ®s, src_file, dst_file); return 0; }