void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) { struct screen *display = gwps->display; if(img->always_display) display->set_drawmode(DRMODE_FG); else display->set_drawmode(DRMODE_SOLID); #if LCD_DEPTH > 1 if(img->bm.format == FORMAT_MONO) { #endif display->mono_bitmap_part(img->bm.data, 0, img->subimage_height * subimage, img->bm.width, img->x, img->y, img->bm.width, img->subimage_height); #if LCD_DEPTH > 1 } else { display->transparent_bitmap_part((fb_data *)img->bm.data, 0, img->subimage_height * subimage, STRIDE(display->screen_type, img->bm.width, img->bm.height), img->x, img->y, img->bm.width, img->subimage_height); } #endif }
/* x,y in pixels */ void screen_put_iconxy(struct screen * display, int xpos, int ypos, enum themable_icons icon) { const void *data; const int screen = display->screen_type; const int width = ICON_WIDTH(screen); const int height = ICON_HEIGHT(screen); const int is_rtl = lang_is_rtl(); int stride; const struct bitmap *iconset; screen_bitmap_part_func *draw_func = NULL; if (icon == Icon_NOICON) { if (is_rtl) xpos = display->getwidth() - xpos - width; screen_clear_area(display, xpos, ypos, width, height); return; } else if (icon >= Icon_Last_Themeable) { iconset = &iconsets[Iconset_viewers][screen].bmp; icon -= Icon_Last_Themeable; if (!iconsets[Iconset_viewers][screen].loaded || (global_status.viewer_icon_count * height > iconset->height) || (icon * height + height > iconset->height)) { screen_put_iconxy(display, xpos, ypos, Icon_Questionmark); return; } } else if (iconsets[Iconset_user][screen].loaded) { iconset = &iconsets[Iconset_user][screen].bmp; } else { iconset = &inbuilt_iconset[screen]; } data = iconset->data; stride = STRIDE(display->screen_type, iconset->width, iconset->height); /* add some left padding to the icons if they are on the edge */ if (xpos == 0) xpos++; if (is_rtl) xpos = display->getwidth() - xpos - width; #if (LCD_DEPTH == 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH == 16) if (display->depth == 16) draw_func = display->transparent_bitmap_part; else #endif draw_func = display->bitmap_part; draw_func(data, 0, height * icon, stride, xpos, ypos, width, height); }
/* draw a spot at the coordinates (x,y), range of p is 0-19 */ static void draw_spot(int p) { rb->lcd_bitmap_part( flipit_tokens, 0, spots[p] * TK_HEIGHT, STRIDE(SCREEN_MAIN, BMPWIDTH_flipit_tokens, BMPHEIGHT_flipit_tokens), GRID_LEFT + (p%5) * (TK_WIDTH+TK_SPACE), GRID_TOP + (p/5) * (TK_HEIGHT+TK_SPACE), TK_WIDTH, TK_HEIGHT ); }
static void matrix_blit_char(const int row, const int col, int cha) { if (cha == 129 || cha == 2 || cha > MAXCHARS) cha = 0; if (matrix[row][col].bold == 1) { rb->lcd_bitmap_part(matrix_bold, cha*COL_W, 0, STRIDE( SCREEN_MAIN, BMPWIDTH_matrix_bold, BMPHEIGHT_matrix_bold), col*COL_W + LEFTMARGIN, row*COL_H + TOPMARGIN, COL_W, COL_H); } else { rb->lcd_bitmap_part(matrix_normal, cha*COL_W, 0, STRIDE( SCREEN_MAIN, BMPWIDTH_matrix_normal, BMPHEIGHT_matrix_normal), col*COL_W + LEFTMARGIN, row*COL_H + TOPMARGIN, COL_W, COL_H); } }
/* draws a spot at the coordinates (x,y), range of p is 1-20 */ static void draw_spot(int p, int x, int y) { int w, h; if (p == HOLE_ID) { #if LCD_DEPTH==1 /* the bottom-right cell of the default sliding_puzzle image is an appropriate hole graphic */ rb->lcd_bitmap_part(sliding_puzzle, ((p-1)%SPOTS_X)*SPOTS_WIDTH, ((p-1)/SPOTS_X)*SPOTS_HEIGHT, STRIDE( SCREEN_MAIN, BMPWIDTH_sliding_puzzle, BMPHEIGHT_sliding_puzzle), x, y, SPOTS_WIDTH, SPOTS_HEIGHT); #else /* just draw a black rectangle */ int old_fg = rb->lcd_get_foreground(); rb->lcd_set_foreground(LCD_BLACK); rb->lcd_fillrect(x,y,SPOTS_WIDTH,SPOTS_HEIGHT); rb->lcd_set_foreground(LCD_WHITE); rb->lcd_drawrect(x,y,SPOTS_WIDTH,SPOTS_HEIGHT); rb->lcd_set_foreground(old_fg); #endif } else if (picmode != PICMODE_NUMERALS) { rb->lcd_bitmap_part( puzzle_bmp_ptr, ((p-1)%SPOTS_X)*SPOTS_WIDTH, ((p-1)/SPOTS_X)*SPOTS_HEIGHT, STRIDE( SCREEN_MAIN, BMPWIDTH_sliding_puzzle, BMPHEIGHT_sliding_puzzle), x, y, SPOTS_WIDTH, SPOTS_HEIGHT); } else { rb->lcd_drawrect(x, y, SPOTS_WIDTH, SPOTS_HEIGHT); rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); rb->lcd_fillrect(x+1, y+1, SPOTS_WIDTH-2, SPOTS_HEIGHT-2); rb->lcd_set_drawmode(DRMODE_SOLID); rb->snprintf(s, sizeof(s), "%d", p); rb->lcd_setfont(num_font); rb->lcd_getstringsize(s, &w, &h); rb->lcd_putsxy(x + (SPOTS_WIDTH/2) - w / 2, y + (SPOTS_HEIGHT/2) - h / 2, s); } }
/** * Draws a part of the given picture on the given screen * Use it when the data contains multiple pictures from top to bottom. * In that case, picture.slide_height represents the height of one picture, * not the whole set. picture.height represents the height of the whole image * @param display the screen where to display the picture * @param picture the picture's data, only a part will be displayed * @param yoffset display the data in the picture from yoffset to * yoffset+picture.height * @param x abscissa where to put the picture * @param y ordinate where to put the picture */ void vertical_picture_draw_part(struct screen* display, const struct picture* picture, int yoffset, int x, int y){ display->bitmap_part( picture->data, /*slice into picture->data */ 0, yoffset, STRIDE(display->screen_type, picture->width, picture->height), /* Position on the screen */ x, y, picture->width, picture->slide_height ); }
//PAGEBREAK: 32 // Look in the process table for an UNUSED proc. // If found, change state to EMBRYO and initialize // state required to run in the kernel. // Otherwise return 0. static struct proc* allocproc(int stride) { struct proc *p; char *sp; acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) if(p->state == UNUSED) goto found; release(&ptable.lock); return 0; found: p->state = EMBRYO; p->pid = nextpid++; p->passo = STRIDE(stride); p->passada = 0; release(&ptable.lock); // Allocate kernel stack. if((p->kstack = kalloc()) == 0){ p->state = UNUSED; return 0; } sp = p->kstack + KSTACKSIZE; // Leave room for trap frame. sp -= sizeof *p->tf; p->tf = (struct trapframe*)sp; // Set up new context to start executing at forkret, // which returns to trapret. sp -= 4; *(uint*)sp = (uint)trapret; sp -= sizeof *p->context; p->context = (struct context*)sp; memset(p->context, 0, sizeof *p->context); p->context->eip = (uint)forkret; return p; }
/* hack: fix error "undefined reference to `_grey_info'". */ GREY_INFO_STRUCT #endif /* USEGSLIB */ static void draw_image_rect(struct image_info *info, int x, int y, int width, int height) { unsigned char **pdisp = (unsigned char **)info->data; #ifdef HAVE_LCD_COLOR rb->lcd_bitmap_part((fb_data *)*pdisp, info->x + x, info->y + y, STRIDE(SCREEN_MAIN, info->width, info->height), x + MAX(0, (LCD_WIDTH-info->width)/2), y + MAX(0, (LCD_HEIGHT-info->height)/2), width, height); #else mylcd_ub_gray_bitmap_part(*pdisp, info->x + x, info->y + y, info->width, x + MAX(0, (LCD_WIDTH-info->width)/2), y + MAX(0, (LCD_HEIGHT-info->height)/2), width, height); #endif }
void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) { struct screen *display = gwps->display; struct viewport *vp = pb->vp; struct wps_state *state = skin_get_global_state(); struct mp3entry *id3 = state->id3; int x = pb->x, y = pb->y, width = pb->width, height = pb->height; unsigned long length, end; int flags = HORIZONTAL; if (height < 0) height = font_get(vp->font)->height; if (y < 0) { int line_height = font_get(vp->font)->height; /* center the pb in the line, but only if the line is higher than the pb */ int center = (line_height-height)/2; /* if Y was not set calculate by font height,Y is -line_number-1 */ y = line*line_height + (0 > center ? 0 : center); } if (pb->type == SKIN_TOKEN_VOLUMEBAR) { int minvol = sound_min(SOUND_VOLUME); int maxvol = sound_max(SOUND_VOLUME); length = maxvol-minvol; end = global_settings.volume-minvol; } else if (pb->type == SKIN_TOKEN_BATTERY_PERCENTBAR) { length = 100; end = battery_level(); } else if (pb->type == SKIN_TOKEN_PEAKMETER_LEFTBAR || pb->type == SKIN_TOKEN_PEAKMETER_RIGHTBAR) { int left, right, val; peak_meter_current_vals(&left, &right); val = pb->type == SKIN_TOKEN_PEAKMETER_LEFTBAR ? left : right; length = MAX_PEAK; end = peak_meter_scale_value(val, length); } #if CONFIG_TUNER else if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { #ifdef HAVE_RADIO_RSSI if (pb->type == SKIN_TOKEN_TUNER_RSSI_BAR) { int val = tuner_get(RADIO_RSSI); int min = tuner_get(RADIO_RSSI_MIN); int max = tuner_get(RADIO_RSSI_MAX); end = val - min; length = max - min; } else #endif { int min = fm_region_data[global_settings.fm_region].freq_min; end = radio_current_frequency() - min; length = fm_region_data[global_settings.fm_region].freq_max - min; } } #endif else if (id3 && id3->length) { length = id3->length; end = id3->elapsed + state->ff_rewind_count; } else { length = 1; end = 0; } if (!pb->horizontal) { /* we want to fill upwards which is technically inverted. */ flags = INVERTFILL; } if (pb->invert_fill_direction) { flags ^= INVERTFILL; } if (pb->nofill) { flags |= INNER_NOFILL; } if (pb->slider) { struct gui_img *img = pb->slider; /* clear the slider */ screen_clear_area(display, x, y, width, height); /* shrink the bar so the slider is inside bounds */ if (flags&HORIZONTAL) { width -= img->bm.width; x += img->bm.width / 2; } else { height -= img->bm.height; y += img->bm.height / 2; } } if (pb->backdrop) { struct gui_img *img = pb->backdrop; #if LCD_DEPTH > 1 if(img->bm.format == FORMAT_MONO) { #endif display->mono_bitmap_part(img->bm.data, 0, 0, img->bm.width, x, y, width, height); #if LCD_DEPTH > 1 } else { display->transparent_bitmap_part((fb_data *)img->bm.data, 0, 0, STRIDE(display->screen_type, img->bm.width, img->bm.height), x, y, width, height); } #endif flags |= DONT_CLEAR_EXCESS; } if (!pb->nobar) { if (pb->image) gui_bitmap_scrollbar_draw(display, &pb->image->bm, x, y, width, height, length, 0, end, flags); else gui_scrollbar_draw(display, x, y, width, height, length, 0, end, flags); } if (pb->slider) { int xoff = 0, yoff = 0; int w = width, h = height; struct gui_img *img = pb->slider; if (flags&HORIZONTAL) { w = img->bm.width; xoff = width * end / length; if (flags&INVERTFILL) xoff = width - xoff; xoff -= w / 2; } else { h = img->bm.height; yoff = height * end / length; if (flags&INVERTFILL) yoff = height - yoff; yoff -= h / 2; } #if LCD_DEPTH > 1 if(img->bm.format == FORMAT_MONO) { #endif display->mono_bitmap_part(img->bm.data, 0, 0, img->bm.width, x + xoff, y + yoff, w, h); #if LCD_DEPTH > 1 } else { display->transparent_bitmap_part((fb_data *)img->bm.data, 0, 0, STRIDE(display->screen_type, img->bm.width, img->bm.height), x + xoff, y + yoff, w, h); } #endif } if (pb->type == SKIN_TOKEN_PROGRESSBAR) { if (id3 && id3->length) { #ifdef AB_REPEAT_ENABLE if (ab_repeat_mode_enabled()) ab_draw_markers(display, id3->length, x, y, width, height); #endif if (id3->cuesheet) cue_draw_markers(display, id3->cuesheet, id3->length, x, y+1, width, height-2); } #if 0 /* disable for now CONFIG_TUNER */ else if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { presets_draw_markers(display, x, y, width, height); } #endif } }
/*********************************************************************** * pegbox_draw_board() draws the game's current level. ************************************************************************/ static void pegbox_draw_board(struct game_context* pb) { unsigned int r, c, type; pb->num_left = 0; rb->lcd_clear_display(); #ifdef WIDE_LAYOUT rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0, HEADER_WIDTH,LCD_HEIGHT); #else rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0, HEADER_WIDTH, HEADER_HEIGHT); #endif /* WIDE_LAYOUT */ #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT) rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4); #endif /* enough space for a frame? */ #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_WHITE); rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2); rb->lcd_set_foreground(LCD_BLACK); rb->lcd_set_background(TEXT_BG); #endif for (r=0 ; r < ROWS ; r++) { for (c = 0 ; c < COLS ; c++) { type = pb->playboard[r][c]; if(type != SPACE) { rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT, STRIDE( SCREEN_MAIN, BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces), c * PIECE_WIDTH + BOARD_X, r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH, PIECE_HEIGHT); } if(pb->playboard[r][c] == PLAYER) { pb->player_row=r; pb->player_col=c; } else if (type != WALL && type != SPACE && type != HOLE) pb->num_left++; } } #ifdef WIDE_LAYOUT rb->lcd_putsxyf(TEXT_X, LEVEL_TEXT_Y, "%d", pb->level); rb->lcd_putsxyf(TEXT_X, PEGS_TEXT_Y, "%d", pb->num_left); #else rb->lcd_putsxyf(LEVEL_TEXT_X, TEXT_Y, "%d", pb->level); rb->lcd_putsxyf(PEGS_TEXT_X, TEXT_Y, "%d", pb->num_left); #endif /*WIDE_LAYOUT*/ #ifdef HAVE_LCD_COLOR rb->lcd_set_background(BG_COLOR); rb->lcd_set_foreground(LCD_WHITE); #endif /* print out the screen */ rb->lcd_update(); }
/* Draw the album art bitmap from the given handle ID onto the given WPS. Call with clear = true to clear the bitmap instead of drawing it. */ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear) { if (!gwps || !gwps->data || !gwps->display || handle_id < 0) return; struct wps_data *data = gwps->data; struct skin_albumart *aa = data->albumart; if (!aa) return; struct bitmap *bmp; if (bufgetdata(handle_id, 0, (void *)&bmp) <= 0) return; short x = aa->x; short y = aa->y; short width = bmp->width; short height = bmp->height; if (aa->width > 0) { /* Crop if the bitmap is too wide */ width = MIN(bmp->width, aa->width); /* Align */ if (aa->xalign & WPS_ALBUMART_ALIGN_RIGHT) x += aa->width - width; else if (aa->xalign & WPS_ALBUMART_ALIGN_CENTER) x += (aa->width - width) / 2; } if (aa->height > 0) { /* Crop if the bitmap is too high */ height = MIN(bmp->height, aa->height); /* Align */ if (aa->yalign & WPS_ALBUMART_ALIGN_BOTTOM) y += aa->height - height; else if (aa->yalign & WPS_ALBUMART_ALIGN_CENTER) y += (aa->height - height) / 2; } if (!clear) { /* Draw the bitmap */ gwps->display->bitmap_part((fb_data*)bmp->data, 0, 0, STRIDE(gwps->display->screen_type, bmp->width, bmp->height), x, y, width, height); #ifdef HAVE_LCD_INVERT if (global_settings.invert) { gwps->display->set_drawmode(DRMODE_COMPLEMENT); gwps->display->fillrect(x, y, width, height); gwps->display->set_drawmode(DRMODE_SOLID); } #endif } else { /* Clear the bitmap */ gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); gwps->display->fillrect(x, y, width, height); gwps->display->set_drawmode(DRMODE_SOLID); } }