/// If outputDir.isEmpty(), don't write out diff files.
static void create_diff_images (DiffMetricProc dmp,
                                const int colorThreshold,
                                const SkString& baseFile,
                                const SkString& comparisonFile,
                                const SkString& outputDir,
                                const SkString& outputFilename,
                                DiffRecord* drp) {
    SkASSERT(!baseFile.isEmpty());
    SkASSERT(!comparisonFile.isEmpty());

    drp->fBase.fFilename = baseFile;
    drp->fBase.fFullPath = baseFile;
    drp->fBase.fStatus = DiffResource::kSpecified_Status;

    drp->fComparison.fFilename = comparisonFile;
    drp->fComparison.fFullPath = comparisonFile;
    drp->fComparison.fStatus = DiffResource::kSpecified_Status;

    SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str()));
    if (baseFileBits) {
        drp->fBase.fStatus = DiffResource::kRead_Status;
    }
    SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str()));
    if (comparisonFileBits) {
        drp->fComparison.fStatus = DiffResource::kRead_Status;
    }
    if (nullptr == baseFileBits || nullptr == comparisonFileBits) {
        if (nullptr == baseFileBits) {
            drp->fBase.fStatus = DiffResource::kCouldNotRead_Status;
        }
        if (nullptr == comparisonFileBits) {
            drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status;
        }
        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        return;
    }

    if (are_buffers_equal(baseFileBits, comparisonFileBits)) {
        drp->fResult = DiffRecord::kEqualBits_Result;
        return;
    }

    get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode);
    get_bitmap(comparisonFileBits, drp->fComparison, SkImageDecoder::kDecodePixels_Mode);
    if (DiffResource::kDecoded_Status != drp->fBase.fStatus ||
        DiffResource::kDecoded_Status != drp->fComparison.fStatus)
    {
        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        return;
    }

    create_and_write_diff_image(drp, dmp, colorThreshold, outputDir, outputFilename);
    //TODO: copy fBase.fFilename and fComparison.fFilename to outputDir
    //      svn and git often present tmp files to diff tools which are promptly deleted

    //TODO: serialize drp to outputDir
    //      write a tool to deserialize them and call print_diff_page

    SkASSERT(DiffRecord::kUnknown_Result != drp->fResult);
}
示例#2
0
void draw_level(BITMAP *bmp)
{
  int doors_count;
  int x, y, flags;
  int xget, yget;

  /* background */
  blit(get_bitmap(level->bg), bmp, 0, 0, 0, 0, GAME_W, GAME_H);

  /* blocks */
  doors_count = 0;
  for (y=0; y<LEVEL_HEIGHT; y++)
    for (x=0; x<LEVEL_WIDTH; x++) {
      flags = get_block_flags(x, y);

      xget = -1;
      yget = -1;

      if (!(flags & BLOCK_FLAG_BUBBLE)) {
        if (flags & BLOCK_FLAG_EXIT) {
          if (doors_time < 0)
            xget = 0;
          else {
            if (doors_count >= doors)
              xget = 0;
            else if (doors_time < FRAMES_PER_SECOND/2)
              xget = 2 * doors_time / (FRAMES_PER_SECOND/2);
            else
              xget = 2 - 2 * (doors_time-FRAMES_PER_SECOND/2) / (FRAMES_PER_SECOND/4);

            xget = MID(0, xget, 2);
          }
          yget = 1;
          doors_count++;
        }
        else if (flags != 0) {
          xget = (flags & BLOCK_FLAG_TRAP)? 1: 0;
          yget = 0;
        }
      }

      if ((xget >= 0) && (yget >= 0)) {
        masked_blit(get_bitmap(BMP_BLOCKS), bmp,
          xget*BLOCK_WIDTH, yget*BLOCK_HEIGHT,
             x*BLOCK_WIDTH,    y*BLOCK_HEIGHT,
               BLOCK_WIDTH,      BLOCK_HEIGHT+yget*BLOCK_HEIGHT*2);
      }
    }

  /* funnel */
  triangle(bmp, funnel.x1, funnel.y1+BLOCK_HEIGHT,
                crusher.x, crusher.y,
                funnel.x1, funnel.y1+BLOCK_HEIGHT*3/2, makecol(128, 128, 0));

  triangle(bmp, funnel.x2, funnel.y2+BLOCK_HEIGHT,
                crusher.x+crusher.w, crusher.y,
                funnel.x2, funnel.y2+BLOCK_HEIGHT*3/2, makecol(128, 128, 0));
}
示例#3
0
void add_death_donkey(DONKEY *donkey, int clockwise)
{
  death_donkey[death_donkey_count].time = 0;
  death_donkey[death_donkey_count].x = donkey->x*BLOCK_WIDTH/2+BLOCK_WIDTH/2-get_bitmap(BMP_DONKEY)->w/2;
  death_donkey[death_donkey_count].y = donkey->y*BLOCK_HEIGHT/2+BLOCK_HEIGHT/2-get_bitmap(BMP_DONKEY)->h/2-4;
  death_donkey[death_donkey_count].color = donkey->color;
  death_donkey[death_donkey_count].clockwise = clockwise;
  death_donkey[death_donkey_count].flip = donkey->flip;
  death_donkey_count++;
}
示例#4
0
// your custom drawing function
void quan::uav::osd::on_draw()
{
    draw_text("Hello World",{-60,30}); 
    draw_line ( {-120,-100}, {80,100}, colour_type::white ); // white
    draw_line ( {-100,-100}, {100,100}, colour_type::black ); // black
    draw_bitmap(get_bitmap(BitmapID::home_arrow),{50,-50});
}
示例#5
0
int main()
{
    get_bitmap();
    index_bitmap();
    return 0;

}
示例#6
0
static void get_bounds(DiffResource& resource, const char* name) {
    if (resource.fBitmap.empty() && !DiffResource::isStatusFailed(resource.fStatus)) {
        sk_sp<SkData> fileBits(read_file(resource.fFullPath.c_str()));
        if (fileBits) {
            get_bitmap(fileBits.get(), resource, true);
        } else {
            SkDebugf("WARNING: couldn't read %s file <%s>\n", name, resource.fFullPath.c_str());
            resource.fStatus = DiffResource::kCouldNotRead_Status;
        }
    }
}
示例#7
0
static void get_bounds(DiffResource& resource, const char* name) {
    if (resource.fBitmap.empty() && !DiffResource::isStatusFailed(resource.fStatus)) {
        SkAutoDataUnref fileBits(read_file(resource.fFullPath.c_str()));
        if (NULL == fileBits) {
            SkDebugf("WARNING: couldn't read %s file <%s>\n", name, resource.fFullPath.c_str());
            resource.fStatus = DiffResource::kCouldNotRead_Status;
        } else {
            get_bitmap(fileBits, resource, SkImageDecoder::kDecodeBounds_Mode);
        }
    }
}
示例#8
0
void log_bitmap(unsigned char *map, int size)
{
	log_msg("bitmap:\n"); 
	int i=0;
	for(i=0; i<size; i++)
	{
		log_msg("%d",get_bitmap(map, i, size));
		if((i+1)%32==0)
			log_msg("\n");
	}
	log_msg("\n");
}
void EmojiFont::Draw(SkCanvas* canvas, uint16_t glyphID,
                     SkScalar x, SkScalar y, const SkPaint& paint) {
    if (glyphID < kGlyphBase) {
        SkDebugf("-------- bad glyph passed to EmojiFont::Draw %d\n", glyphID);
    }

    const SkBitmap* bitmap = get_bitmap(glyphID - kGlyphBase);
    if (bitmap && !bitmap->empty()) {
        SkRect dst;
        SkScalar size = paint.getTextSize();
        y += SkScalarMul(size, gBaselinePercentDrop);
        dst.set(x, y - size, x + size, y);
        canvas->drawBitmapRect(*bitmap, NULL, dst, &paint);
    }
}
SkScalar EmojiFont::GetAdvanceWidth(uint16_t glyphID, const SkPaint& paint) {
    if (glyphID < kGlyphBase) {
        SkDebugf("-------- bad glyph passed to EmojiFont::GetAdvanceWidth %d\n",
                 glyphID);
        return 0;
    }

    const SkBitmap* bitmap = get_bitmap(glyphID - kGlyphBase);
    if (NULL == bitmap) {
        return 0;
    }

    // assume that our advance width is always the pointsize
    return paint.getTextSize();
}
示例#11
0
void draw_donkeys(BITMAP *bmp)
{
  int x1, y1, x2, y2;
  DONKEY *donkey;
  int i, x, y;

  /* draw normal donkeys */
  for (donkey=donkey_list; donkey; donkey=donkey->next) {
    draw_a_donkey(bmp,
      (move_time) < ((FRAMES_PER_SECOND/2)*move_freq/1000)?
        get_bitmap(BMP_DONKEY): get_bitmap(BMP_DONKEY_WALK),
      donkey->x*BLOCK_WIDTH/2+BLOCK_WIDTH/2-get_bitmap(BMP_DONKEY)->w/2,
      donkey->y*BLOCK_HEIGHT/2+BLOCK_HEIGHT/2-get_bitmap(BMP_DONKEY)->h/2-4,
      donkey->color, donkey->flip, itofix(1), itofix(1));
  }

  /* draw the death donkeys */
  for (i=0; i<death_donkey_count; i++) {
    if (death_donkey[i].time < FRAMES_PER_SECOND/2) {
      x1 = death_donkey[i].x;
      y1 = death_donkey[i].y;
      x2 = death_donkey[i].x;
      y2 = death_donkey[i].y+BLOCK_HEIGHT;

      x = x1 + (x2-x1) * (death_donkey[i].time) / (FRAMES_PER_SECOND/2);
      y = y1 + (y2-y1) * (death_donkey[i].time) / (FRAMES_PER_SECOND/2);
    }
    else {
      x1 = death_donkey[i].x;
      y1 = death_donkey[i].y+BLOCK_HEIGHT;
      x2 = crusher.x+crusher.w/2-get_bitmap(BMP_DONKEY_DEATH)->w/2;
      y2 = crusher.y+crusher.h/2-get_bitmap(BMP_DONKEY_DEATH)->h/2;//+BLOCK_HEIGHT;

      x = x1 + (x2-x1) * (death_donkey[i].time-(FRAMES_PER_SECOND/2)) / (FRAMES_PER_SECOND/2);
      y = y1 + (y2-y1) * (death_donkey[i].time-(FRAMES_PER_SECOND/2)) / (FRAMES_PER_SECOND/2);
    }

    draw_a_donkey(bmp,
      get_bitmap(BMP_DONKEY_DEATH),
      x+rand()%3-1,
      y+rand()%3-1,
      death_donkey[i].color,
      death_donkey[i].flip,
      (death_donkey[i].time < FRAMES_PER_SECOND/2)?
        0:
        (itofix(256) * (death_donkey[i].time-(FRAMES_PER_SECOND/2)) / (FRAMES_PER_SECOND/2))
        * ((death_donkey[i].clockwise)? 1: -1),
      itofix(1));
  }
}
示例#12
0
int process_block(server *srv, chunkqueue *cq, vhd_state_t *state,
		off_t *curr_off)
{
	int err;
	vhd_context_t *vhd;
	off_t blk_off;
	unsigned int bitmap_size;
	size_t bytes;

	vhd = &state->vhd;
	blk_off = (off_t)vhd->bat.bat[state->curr_virt_blk] << VHD_SECTOR_SHIFT;

	DEBUGLOG("sod", "Current Offset:", *curr_off, state->curr_virt_blk);

	if (*curr_off < blk_off) {
		bytes = discard_bytes(srv, cq, blk_off - *curr_off);
		DEBUGLOG("s", "curr_off < blk_off");
		DEBUGLOG("sd", "Discarding bytes:", bytes);
		*curr_off += bytes;
		return 0;
	}

	bitmap_size = vhd->bm_secs << VHD_SECTOR_SHIFT;
	if (*curr_off < blk_off + bitmap_size) {
		return get_bitmap(srv, cq, state, curr_off);
	}

	if (*curr_off < blk_off + bitmap_size + vhd->header.block_size) {
	        DEBUGLOG("so", "Abs_Off", state->abs_off);
		err = write_block(srv, cq, state, curr_off);
		return err;
	}

	/* this block is done */
	state->blocks_written++;
	DEBUGLOG("sd", "Blocks written:", state->blocks_written);
	if (state->blocks_written < state->blocks_allocated) {
		state->curr_virt_blk = find_next_virt_blk(srv, vhd, *curr_off,
				state->curr_virt_blk + 1);
		DEBUGLOG("sd", "Next VHD block:", state->curr_virt_blk);
	} else {
		state->curr_virt_blk = -1;
		DEBUGLOG("s", "No more blocks");
	}

	return 0;
}
示例#13
0
/*===========================================================================*
 *				fs_inodewalker			     *
 *===========================================================================*/
int fs_inodewalker()
{
	/* Get the list of blocks in use by the system from the inode bitmap */
	printf("Inode Walker\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = IMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	init_global();
	imap_disk = alloc_bitmap(N_IMAP);
	printf("Loading inode bitmap from disk ...\n");
	get_bitmap(imap_disk, IMAP);
	printf(" done.\n");
	sleep(3);
	int *list_inodes = get_list_used(imap_disk, IMAP);
	free_bitmap(imap_disk);
	return 0;
}
示例#14
0
文件: ascii2dot.c 项目: yumm007/C
static void lcd_print(FONT_SIZE_T size, int row, int lines, const uint8_t *str) {
	unsigned char is_hz;
	unsigned char bit_buf[FONT_MAX * (FONT_MAX/8)];
	FONT_TYPE_T font_type;

	while (*str != '\0') {
		is_hz = (*str) > 0xa0 ? 1 : 0;	//判断是否为汉字	
		//返回字体类型
		font_type = get_word_type(size, is_hz);
		//设置屏幕输出的起始位置
		set_lcd_row_line(font_type, &row, &lines);

		//从字库中取出当前字的点阵
		memset(bit_buf, 0x0, sizeof(bit_buf));
		get_bitmap(font_type, bit_buf, str);
		send_bitmap(font_type, bit_buf);
		//row, line始终指向下一个空白位置,可能换行也可能跳到行首
		str = is_hz ? str + 2 : str + 1;	//指向下一个字符
	}
}
示例#15
0
/*===========================================================================*
 *				fs_zonewalker			     *
 *===========================================================================*/
int fs_zonewalker()
{
	/* Get the list of blocks used by the system from the zone bitmap */
	printf("Zone Walkder\n");
	printf("Getting super node from device %llu ...\n", fs_dev);
	type = ZMAP;
	sb = get_super(fs_dev);
	read_super(sb);
	lsuper();
	sleep(3);
	init_global();
	zmap_disk = alloc_bitmap(N_ZMAP);
	printf("Loading zone bitmap from disk ...\n");
	get_bitmap(zmap_disk, ZMAP);
	printf(" done.\n\n");
	sleep(3);
	//print_bitmap(zmap_disk);
	int* list = get_list_used(zmap_disk, ZMAP);
	free_bitmap(zmap_disk);
	return 0;
}
示例#16
0
文件: UTFTFont.cpp 项目: JJK801/Cosa
void
UTFTFont::draw(Canvas* canvas, char c, 
	       uint8_t x, uint8_t y, 
	       uint8_t scale)
{
  const uint8_t* bp = get_bitmap(c);
  for (uint8_t i = 0; i < HEIGHT; i++) {
    for (uint8_t j = 0; j < WIDTH; j += 8) {
      uint8_t line = pgm_read_byte(bp++);
      for (uint8_t k = 0; k < 8; k++) {
	if (line & 0x80) {
	  if (scale == 1)
	    canvas->draw_pixel(x + j + k, y + i);
	  else {
	    canvas->fill_rect(x + (j + k)*scale, y + i*scale, scale, scale);
	  } 
	}
	line <<= 1;
      }
    }
  }
}
示例#17
0
/// Creates difference images, returns the number that have a 0 metric.
/// If outputDir.isEmpty(), don't write out diff files.
static void create_diff_images (DiffMetricProc dmp,
                                const int colorThreshold,
                                RecordArray* differences,
                                const SkString& baseDir,
                                const SkString& comparisonDir,
                                const SkString& outputDir,
                                const StringArray& matchSubstrings,
                                const StringArray& nomatchSubstrings,
                                bool recurseIntoSubdirs,
                                bool getBounds,
                                bool verbose,
                                DiffSummary* summary) {
    SkASSERT(!baseDir.isEmpty());
    SkASSERT(!comparisonDir.isEmpty());

    FileArray baseFiles;
    FileArray comparisonFiles;

    get_file_list(baseDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &baseFiles);
    get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
                  &comparisonFiles);

    if (!baseFiles.isEmpty()) {
        qsort(baseFiles.begin(), baseFiles.count(), sizeof(SkString*),
              SkCastForQSort(compare_file_name_metrics));
    }
    if (!comparisonFiles.isEmpty()) {
        qsort(comparisonFiles.begin(), comparisonFiles.count(),
              sizeof(SkString*), SkCastForQSort(compare_file_name_metrics));
    }

    int i = 0;
    int j = 0;

    while (i < baseFiles.count() &&
           j < comparisonFiles.count()) {

        SkString basePath(baseDir);
        SkString comparisonPath(comparisonDir);

        DiffRecord *drp = new DiffRecord;
        int v = strcmp(baseFiles[i]->c_str(), comparisonFiles[j]->c_str());

        if (v < 0) {
            // in baseDir, but not in comparisonDir
            drp->fResult = DiffRecord::kCouldNotCompare_Result;

            basePath.append(*baseFiles[i]);
            comparisonPath.append(*baseFiles[i]);

            drp->fBase.fFilename = *baseFiles[i];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kExists_Status;

            drp->fComparison.fFilename = *baseFiles[i];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status;

            VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, baseFiles[i]);

            ++i;
        } else if (v > 0) {
            // in comparisonDir, but not in baseDir
            drp->fResult = DiffRecord::kCouldNotCompare_Result;

            basePath.append(*comparisonFiles[j]);
            comparisonPath.append(*comparisonFiles[j]);

            drp->fBase.fFilename = *comparisonFiles[j];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kDoesNotExist_Status;

            drp->fComparison.fFilename = *comparisonFiles[j];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kExists_Status;

            VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, comparisonFiles[j]);

            ++j;
        } else {
            // Found the same filename in both baseDir and comparisonDir.
            SkASSERT(DiffRecord::kUnknown_Result == drp->fResult);

            basePath.append(*baseFiles[i]);
            comparisonPath.append(*comparisonFiles[j]);

            drp->fBase.fFilename = *baseFiles[i];
            drp->fBase.fFullPath = basePath;
            drp->fBase.fStatus = DiffResource::kExists_Status;

            drp->fComparison.fFilename = *comparisonFiles[j];
            drp->fComparison.fFullPath = comparisonPath;
            drp->fComparison.fStatus = DiffResource::kExists_Status;

            SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str()));
            if (baseFileBits) {
                drp->fBase.fStatus = DiffResource::kRead_Status;
            }
            SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str()));
            if (comparisonFileBits) {
                drp->fComparison.fStatus = DiffResource::kRead_Status;
            }
            if (NULL == baseFileBits || NULL == comparisonFileBits) {
                if (NULL == baseFileBits) {
                    drp->fBase.fStatus = DiffResource::kCouldNotRead_Status;
                    VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, baseFiles[i]);
                }
                if (NULL == comparisonFileBits) {
                    drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status;
                    VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, comparisonFiles[j]);
                }
                drp->fResult = DiffRecord::kCouldNotCompare_Result;

            } else if (are_buffers_equal(baseFileBits, comparisonFileBits)) {
                drp->fResult = DiffRecord::kEqualBits_Result;
                VERBOSE_STATUS("MATCH", ANSI_COLOR_GREEN, baseFiles[i]);
            } else {
                AutoReleasePixels arp(drp);
                get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode);
                get_bitmap(comparisonFileBits, drp->fComparison,
                           SkImageDecoder::kDecodePixels_Mode);
                VERBOSE_STATUS("DIFFERENT", ANSI_COLOR_RED, baseFiles[i]);
                if (DiffResource::kDecoded_Status == drp->fBase.fStatus &&
                    DiffResource::kDecoded_Status == drp->fComparison.fStatus) {
                    create_and_write_diff_image(drp, dmp, colorThreshold,
                                                outputDir, drp->fBase.fFilename);
                } else {
                    drp->fResult = DiffRecord::kCouldNotCompare_Result;
                }
            }

            ++i;
            ++j;
        }

        if (getBounds) {
            get_bounds(*drp);
        }
        SkASSERT(DiffRecord::kUnknown_Result != drp->fResult);
        differences->push(drp);
        summary->add(drp);
    }

    for (; i < baseFiles.count(); ++i) {
        // files only in baseDir
        DiffRecord *drp = new DiffRecord();
        drp->fBase.fFilename = *baseFiles[i];
        drp->fBase.fFullPath = baseDir;
        drp->fBase.fFullPath.append(drp->fBase.fFilename);
        drp->fBase.fStatus = DiffResource::kExists_Status;

        drp->fComparison.fFilename = *baseFiles[i];
        drp->fComparison.fFullPath = comparisonDir;
        drp->fComparison.fFullPath.append(drp->fComparison.fFilename);
        drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status;

        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        if (getBounds) {
            get_bounds(*drp);
        }
        differences->push(drp);
        summary->add(drp);
    }

    for (; j < comparisonFiles.count(); ++j) {
        // files only in comparisonDir
        DiffRecord *drp = new DiffRecord();
        drp->fBase.fFilename = *comparisonFiles[j];
        drp->fBase.fFullPath = baseDir;
        drp->fBase.fFullPath.append(drp->fBase.fFilename);
        drp->fBase.fStatus = DiffResource::kDoesNotExist_Status;

        drp->fComparison.fFilename = *comparisonFiles[j];
        drp->fComparison.fFullPath = comparisonDir;
        drp->fComparison.fFullPath.append(drp->fComparison.fFilename);
        drp->fComparison.fStatus = DiffResource::kExists_Status;

        drp->fResult = DiffRecord::kCouldNotCompare_Result;
        if (getBounds) {
            get_bounds(*drp);
        }
        differences->push(drp);
        summary->add(drp);
    }

    release_file_list(&baseFiles);
    release_file_list(&comparisonFiles);
}
示例#18
0
void draw_crusher(BITMAP *bmp)
{
  static fixed angle = 0;
  int x, y, x1, y1, x2, y2;

  x = crusher.x+crusher.w/2-get_bitmap(BMP_CRUSHER)->w/2;
  y = crusher.y+crusher.h/2-get_bitmap(BMP_CRUSHER)->h/2+8;

  /* crusher body */
  draw_sprite(bmp, get_bitmap(BMP_CRUSHER), x, y);

  /* crusher motor */
  draw_sprite(bmp, get_bitmap(BMP_CRUSHER_MOTOR),
    x1 = x-get_bitmap(BMP_CRUSHER_MOTOR)->w+1+rand()%3-1,
    y1 = y+rand()%3-1);

  /* crusher pulley */
  rotate_sprite(bmp, get_bitmap(BMP_CRUSHER_PULLEY),
    x2 = x+17-get_bitmap(BMP_CRUSHER_PULLEY)->w/2+rand()%3-1,
    y2 = y+13-get_bitmap(BMP_CRUSHER_PULLEY)->h/2+rand()%3-1,
    angle);

  /* strap */
  do_line(bmp, x1+12, y1+8,
    x2+get_bitmap(BMP_CRUSHER_PULLEY)->w/2-1, y2,
    makecol(0, 0, 0), strap_proc);

  do_line(bmp, x1+12, y1+18,
    x2+get_bitmap(BMP_CRUSHER_PULLEY)->w/2-1,
    y2+get_bitmap(BMP_CRUSHER_PULLEY)->h-1,
    makecol(0, 0, 0), strap_proc);

  angle = fadd(angle, itofix(16));
  if (angle > itofix(256))
    angle = fsub(angle, itofix(256));

  /* scorer */
  draw_sprite(bmp, get_bitmap(BMP_SCORER),
    x+get_bitmap(BMP_CRUSHER)->w,
    y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h);

  /* alarm */
  if (alarm_time_blue >= 0) {
    masked_blit(get_bitmap(BMP_SCORER_ALARM), bmp, 0, 0,
      x+get_bitmap(BMP_CRUSHER)->w+63,
      y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h+27, 8, 9);
  }

  if (alarm_time_red >= 0) {
    masked_blit(get_bitmap(BMP_SCORER_ALARM), bmp,
      get_bitmap(BMP_SCORER_ALARM)->w-8, 0,
      x+get_bitmap(BMP_CRUSHER)->w+75,
      y+get_bitmap(BMP_CRUSHER)->h-get_bitmap(BMP_SCORER)->h+27, 8, 9);
  }
}