void CL_PixelCanvas::modified_framebuffer() { pipeline->wait_for_workers(); CL_SWRenderFrameBufferProvider *gdi_framebuffer = dynamic_cast<CL_SWRenderFrameBufferProvider *>(framebuffer.get_provider()); colorbuffer0.set(gdi_framebuffer->get_colorbuffer0()); pipeline->queue(new(pipeline.get()) CL_PixelCommandSetFrameBuffer(colorbuffer0)); CL_Rect rect = clip_rect; clip_rect = CL_Rect(CL_Point(0,0),colorbuffer0.size); if (cliprect_set) set_clip_rect(rect); else pipeline->queue(new(pipeline.get()) CL_PixelCommandSetClipRect(clip_rect)); }
/* fudge_bitmap: * Makes b2 be similar to b1 (duplicate clip settings, ID, etc). */ static void fudge_bitmap(BITMAP *b1, BITMAP *b2, int copy) { int s, x1, y1, x2, y2; set_clip_state(b2, FALSE); if (copy) blit(b1, b2, 0, 0, 0, 0, b1->w, b1->h); get_clip_rect(b1, &x1, &y1, &x2, &y2); s = get_clip_state(b1); set_clip_rect(b2, x1, y1, x2, y2); set_clip_state(b2, s); }
/* add_clip_rect: * Makes the new clipping rectangle the intersection between the given * rectangle and the current one. */ void add_clip_rect(BITMAP *bitmap, int x1, int y1, int x2, int y2) { int cx1, cy1, cx2, cy2; ASSERT(bitmap); get_clip_rect(bitmap, &cx1, &cy1, &cx2, &cy2); x1 = MAX(x1, cx1); y1 = MAX(y1, cy1); x2 = MIN(x2, cx2); y2 = MIN(y2, cy2); set_clip_rect(bitmap, x1, y1, x2, y2); }
void CL_PixelCanvas::resize(const CL_Size &size) { CL_Size old_size = colorbuffer0.size; primary_colorbuffer0 = CL_PixelBuffer(size.width, size.height, cl_argb8); if (!framebuffer_set) { pipeline->wait_for_workers(); colorbuffer0.set(primary_colorbuffer0); pipeline->queue(new(pipeline.get()) CL_PixelCommandSetFrameBuffer(colorbuffer0)); CL_Rect rect = clip_rect; clip_rect = (CL_Point(0,0),size); if (cliprect_set) set_clip_rect(rect); else pipeline->queue(new(pipeline.get()) CL_PixelCommandSetClipRect(clip_rect)); } }
void CL_PixelCanvas::reset_framebuffer() { pipeline->wait_for_workers(); framebuffer_set = false; slot_framebuffer_modified = CL_Slot(); colorbuffer0.set(primary_colorbuffer0); pipeline->queue(new(pipeline.get()) CL_PixelCommandSetFrameBuffer(colorbuffer0)); framebuffer = CL_FrameBuffer(); CL_Rect rect = clip_rect; clip_rect = CL_Rect(CL_Point(0,0),colorbuffer0.size); if (cliprect_set) set_clip_rect(rect); else pipeline->queue(new(pipeline.get()) CL_PixelCommandSetClipRect(clip_rect)); }
void AllegroGraphics::popClipArea() { Graphics::popClipArea(); if (mClipStack.empty()) { return; } const ClipRectangle& cr = mClipStack.top(); // Allegro won't let you set clip areas //that have zero width or height // so we have to check for that. if (cr.width == 0 || cr.height == 0) { mClipNull = true; } else { mClipNull = false; #if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION == 0 set_clip(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1); #else set_clip_rect(mTarget, cr.x, cr.y, cr.x + cr.width - 1, cr.y + cr.height - 1); #endif } }
void CL_PixelCanvas::set_framebuffer(const CL_FrameBuffer &buffer) { pipeline->wait_for_workers(); CL_SWRenderFrameBufferProvider *gdi_framebuffer = dynamic_cast<CL_SWRenderFrameBufferProvider *>(buffer.get_provider()); if (!gdi_framebuffer) { throw CL_Exception("Invalid FrameBuffer"); } framebuffer_set = true; framebuffer = buffer; slot_framebuffer_modified = gdi_framebuffer->get_sig_changed_event().connect(this, &CL_PixelCanvas::modified_framebuffer); colorbuffer0.set(gdi_framebuffer->get_colorbuffer0()); pipeline->queue(new(pipeline.get()) CL_PixelCommandSetFrameBuffer(colorbuffer0)); CL_Rect rect = clip_rect; clip_rect = CL_Rect(CL_Point(0,0),colorbuffer0.size); if (cliprect_set) set_clip_rect(rect); else pipeline->queue(new(pipeline.get()) CL_PixelCommandSetClipRect(clip_rect)); }
void AllegroGUIRenderer::pushClipRect(int x, int y, int w, int h) { adjustPoint(x, y); ClipRect newCR; if(clipRectStack.empty()) { newCR.x1=x; newCR.y1=y; newCR.x2=x+w-1; newCR.y2=y+h-1; } else { ClipRect& current=clipRectStack.top(); newCR.x1=max(x, current.x1); newCR.y1=max(y, current.y1); newCR.x2=min(x+w-1, current.x2); newCR.y2=min(y+h-1, current.y2); } set_clip_rect(target, newCR.x1, newCR.y1, newCR.x2, newCR.y2); clipRectStack.push(newCR); }
void Bitmap::SetClip(const Rect &rc) { set_clip_rect(_alBitmap, rc.Left, rc.Top, rc.Right, rc.Bottom); }
void TB_SaveSelect::DrawExtendedInfo() { Profile *p = &fProfiles[fCurSel]; int x, y, s; if (fPicXOffset < 0) { fPicXOffset += 8; set_clip_rect(MSG_X+4, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } // player pic draw_sprite((MSG_X+8) + fPicXOffset, MSG_NORMAL_Y+8, SPR_SELECTOR_ARMS); x = (MSG_X + 12) + fPicXOffset; y = MSG_NORMAL_Y + 12; s = (p->equipmask & EQUIP_MIMIGA_MASK) ? SPR_MYCHAR_MIMIGA : SPR_MYCHAR; draw_sprite(x, y, s, 0, RIGHT); // player gun if (p->curWeapon != WPN_NONE && p->curWeapon != WPN_BLADE) { int spr, frame; GetSpriteForGun(p->curWeapon, 0, &spr, &frame); draw_sprite_at_dp(x + sprites[s].frame[0].dir[RIGHT].actionpoint.x, \ y + sprites[s].frame[0].dir[RIGHT].actionpoint.y, \ spr, frame, RIGHT); } clear_clip_rect(); // whimsical stars if (p->equipmask & EQUIP_WHIMSTAR) { x = MSG_X + 12; for(int i=0;i<3;i++) { static int frames[] = { 1, 0, 2 }; draw_sprite(x, y+20, SPR_WHIMSICAL_STAR, frames[i]); x += 10; } } // WEAPONS: x = MSG_X + 64; y = MSG_NORMAL_Y + 8; // weapon list for(int i=0;i<WPN_COUNT;i++) { if (p->weapons[i].hasWeapon) { draw_sprite(x, y, SPR_ARMSICONS, i); x += 20; } } // xp of current weapon if (p->curWeapon != WPN_NONE) { int xb = MSG_X + 64; int yb = MSG_NORMAL_Y + 26; int level = p->weapons[p->curWeapon].level; int curxp = p->weapons[p->curWeapon].xp; int maxxp = player->weapons[p->curWeapon].max_xp[level]; draw_sprite(xb, yb, SPR_XPLEVELICON); xb += 16; draw_sprite(xb, yb, SPR_WHITENUMBERS, level+1); xb += 8; draw_sprite(xb, yb, SPR_XPBAR); if ((curxp == maxxp) && level == 2) draw_sprite(xb, yb, SPR_XPBAR, 3); // MAX else DrawPercentage(xb, yb, SPR_XPBAR, 1, curxp, maxxp, sprites[SPR_XPBAR].w); } // ITEMS: x = (MSG_X + 64) - 10; y = MSG_NORMAL_Y + 40; // Booster // items list. I generally tried to put the ones that are temporary and indicate a // quantity of stage completion at the front so they'll be more likely to be visible. static int items[] = { ITEM_BOOSTER08, ITEM_BOOSTER20, ITEM_LIFE_POT, ITEM_PUPPY, ITEM_JELLYFISH_JUICE, ITEM_CHARCOAL, ITEM_GUM_BASE, ITEM_EXPLOSIVE, ITEM_SPRINKLER, ITEM_CONTROLLER, ITEM_MA_PIGNON, ITEM_LITTLE_MAN, -1 }; for(int i=0;items[i] != -1;i++) { if (CheckInventoryList(items[i], p->inventory, p->ninventory) != -1) { draw_sprite(x, y, SPR_ITEMIMAGE, items[i]); x += 28; if (x + sprites[SPR_ITEMIMAGE].w > (MSG_X + MSG_W) - 8) break; } } // health DrawHealth((MSG_X+MSG_W) - 4, MSG_NORMAL_Y+8, p); }
/** * Show credits with list of contributors. * * Names of people are shown scrolling up like in movie-credits.\n * Uses map from wesnoth or campaign as background. */ void show_about(CVideo &video, const std::string &campaign) { boost::scoped_ptr<cursor::setter> cur(new cursor::setter(cursor::WAIT)); surface& screen = video.getSurface(); if (screen == nullptr) return; // If the title is multi-line, we need to split it accordingly or we // get slight scrolling glitches in the credits screen. std::vector<std::string> text = about::get_text(campaign, true); SDL_Rect screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); const surface_restorer restorer(&video, screen_rect); cur.reset(); std::vector<std::string> image_list; if(campaign.size() && !images[campaign].empty()){ image_list = utils::parenthetical_split(images[campaign], ','); } else{ image_list = utils::parenthetical_split(images_default, ','); } surface map_image, map_image_scaled; if(!image_list.empty()) { map_image = image::get_image(image_list[0]); } else { image_list.push_back(""); } if(!map_image){ image_list[0]=game_config::images::game_title_background; map_image=image::get_image(image_list[0]); } gui::button close(video,_("Close")); close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); const int def_size = font::SIZE_XLARGE; const SDL_Color def_color = font::NORMAL_COLOR; //substitute in the correct control characters for '+' and '-' std::string before_header(2, ' '); before_header[0] = font::LARGE_TEXT; for(unsigned i = 0; i < text.size(); ++i) { std::string &s = text[i]; if (s.empty()) continue; char &first = s[0]; if (first == '-') first = font::SMALL_TEXT; else if (first == '+') { first = font::LARGE_TEXT; text.insert(text.begin() + i, before_header); ++i; } } text.insert(text.begin(), 10, before_header); int startline = 0; //TODO: use values proportional to screen ? // distance from top of map image to top of scrolling text const int top_margin = 60; // distance from bottom of scrolling text to bottom of map image const int bottom_margin = 40; // distance from left of scrolling text to the frame border const int text_left_padding = screen->w/32; int offset = 0; bool is_new_line = true; int first_line_height = 0; SDL_Rect frame_area; // we use a dialog to contains the text. Strange idea but at least the style // will be consistent with the titlescreen gui::dialog_frame f(video, "", gui::dialog_frame::titlescreen_style, false); // the text area's dimensions SDL_Rect text_rect = { 0, 0, 0, 0 }; // we'll retain a copy to prevent SDL_blit to change its w and h SDL_Rect text_rect_blit; surface text_surf; CKey key; bool last_escape; int image_count = 0; int scroll_speed = 4; // scroll_speed*50 = speed of scroll in pixel per second // Initially redraw all bool redraw_mapimage = true; bool update_dimensions = true; int max_text_width = 0; do { last_escape = key[SDLK_ESCAPE] != 0; // check to see if background image has changed if(text.size() && (image_count < ((startline * static_cast<int>(image_list.size())) / static_cast<int>(text.size())))){ image_count++; surface temp=image::get_image(image_list[image_count]); map_image=temp?temp:map_image; redraw_mapimage = true; } if (update_dimensions) { // rescale the background map_image_scaled = scale_surface(map_image, screen->w, screen->h); screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); redraw_mapimage = true; // update the frame frame_area = sdl::create_rect( screen->w * 3 / 32 , top_margin , screen->w * 13 / 16 , screen->h - top_margin - bottom_margin); text_rect = f.layout(frame_area).interior; // update the text area text_rect.x += text_left_padding; text_rect.w -= text_left_padding; text_rect_blit = text_rect; text_surf = create_compatible_surface(screen, text_rect.w, text_rect.h); SDL_SetAlpha(text_surf, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); // relocate the close button close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); update_dimensions = false; } if (redraw_mapimage) { // draw map to screen, thus erasing all text sdl_blit(map_image_scaled, nullptr, screen, nullptr); update_rect(screen_rect); // redraw the dialog f.draw_background(); f.draw_border(); // cache the dialog background (alpha blending + blurred map) sdl_blit(screen, &text_rect, text_surf, nullptr); redraw_mapimage = false; } else { // redraw the saved part of the dialog where text scrolled // thus erasing all text SDL_Rect modified = sdl::create_rect(0, 0, max_text_width, text_rect.h); sdl_blit(text_surf, &modified, screen, &text_rect_blit); update_rect(text_rect); } int y = text_rect.y - offset; int line = startline; max_text_width = 0; { // clip to keep text into the frame (thus the new code block) clip_rect_setter set_clip_rect(screen, &text_rect); const int line_spacing = 5; do { // draw the text (with ellipsis if needed) // update the max_text_width for future cleaning int w = font::draw_text(&video, text_rect, def_size, def_color, text[line], text_rect.x, y).w; max_text_width = std::max<int>(max_text_width, w); // since the real drawing on screen is clipped, // we do a dummy one to get the height of the not clipped line. // (each time because special format characters may change it) const int line_height = font::draw_text(nullptr, text_rect, def_size, def_color, text[line], 0,0).h; if(is_new_line) { is_new_line = false; first_line_height = line_height + line_spacing; } line++; if(size_t(line) > text.size()-1) line = 0; y += line_height + line_spacing; } while(y < text_rect.y + text_rect.h); } // performs the actual scrolling offset += scroll_speed; if (offset>=first_line_height) { offset -= first_line_height; is_new_line = true; startline++; if(size_t(startline) == text.size()){ startline = 0; image_count = -1; } } // handle events if (key[SDLK_UP] && scroll_speed < 20) { ++scroll_speed; } if (key[SDLK_DOWN] && scroll_speed > 0) { --scroll_speed; } if (screen->w != screen_rect.w || screen->h != screen_rect.h) { update_dimensions = true; } events::pump(); events::raise_process_event(); events::raise_draw_event(); // flip screen and wait, so the text does not scroll too fast video.flip(); CVideo::delay(20); } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE])); }
/** * Draw the list, start from startId, until the max icons in the list to be drawn. * * @param startId */ void cBuildingListDrawer::drawList(cBuildingList *list, int listIDToDraw, int startId, bool shouldDrawStructureSize) { // starting draw coordinates int iDrawX=getDrawX(); int iDrawY=getDrawY(); int maxYClip = maxListYCoordinate; int minYClip = 45; int minXClip = game.screen_x - 69; int maxXClip = game.screen_x; set_clip_rect(bmp_screen, minXClip, minYClip, maxXClip, maxYClip); int end = startId + maximumItemsToDraw; // max 5 icons are showed at once // is building an item in the list? bool isBuildingItemInList = list->isBuildingItem(); // draw the icons for (int i = startId; i < end; i++) { cBuildingListItem * item = list->getItem(i); if (item == NULL) { break; // stop. List became empty. } int iDrawXEnd = iDrawX + 63; int iDrawYEnd = iDrawY + 47; // icon id must be set , assert it. assert(item->getIconId() > -1); rect(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, makecol(255, 255, 255)); line(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, makecol(255, 255, 255)); draw_sprite(bmp_screen, (BITMAP *)gfxinter[item->getIconId()].dat, iDrawX, iDrawY); if (shouldDrawStructureSize) { drawStructureSize(item->getBuildId(), iDrawX, iDrawY); } bool cannotPayIt = item->getBuildCost() > player[HUMAN].credits; // when this item is being built. if (item->isBuilding()) { int iTotalBuildPoints = 0; // get the total build time if (listIDToDraw == LIST_CONSTYARD) { iTotalBuildPoints = structures[item->getBuildId()].build_time; } else if (listIDToDraw != LIST_STARPORT) { iTotalBuildPoints = units[item->getBuildId()].build_time; } // Now calculate the right frame. float iPiece = iTotalBuildPoints / 31; // = 17 - 1 (of above) if (iPiece < 0.1) { iPiece = 0.1; } int iFrame = health_bar(31, item->getProgress(), iTotalBuildPoints); if (iFrame > 31) { iFrame = 31; } if (item->getProgress() < iTotalBuildPoints) { // draw the other progress stuff set_trans_blender(0, 0, 0, 128); draw_trans_sprite(bmp_screen, (BITMAP *)gfxinter[PROGRESSFIX].dat, iDrawX+2, iDrawY+2); draw_trans_sprite(bmp_screen, (BITMAP *)gfxinter[PROGRESS001+iFrame].dat, iDrawX+2, iDrawY+2); } else { // draw 'ready' text when done building. if (listIDToDraw == LIST_CONSTYARD) { draw_sprite(bmp_screen, (BITMAP *)gfxinter[READY01].dat, iDrawX+3, iDrawY+16); } } } else { // this item is not being built. So we do not draw a progress indicator. // however, it could be that an other item is being built. // draw the item 'unavailable' when: // - is not available (doh) // - we cant pay it // - some other item is being built // - list is being upgraded, so you cannot build items /*|| cannotPayIt*/ if (!item->isAvailable() || isBuildingItemInList || list->isUpgrading() || !list->isAcceptsOrders()) { set_trans_blender(0,0,0,128); fblend_trans((BITMAP *)gfxinter[PROGRESSNA].dat, bmp_screen, iDrawX, iDrawY, 64); } if (list->getType() == LIST_STARPORT) { if (cannotPayIt) { set_trans_blender(0,0,0,128); fblend_trans((BITMAP *)gfxinter[PROGRESSNA].dat, bmp_screen, iDrawX, iDrawY, 64); rect(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, makecol(game.fade_select, 0, 0)); line(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, makecol(game.fade_select, 0, 0)); line(bmp_screen, iDrawX, iDrawY+47, iDrawX+63, iDrawY, makecol(game.fade_select, 0, 0)); set_trans_blender(0,0,0,128); } } // last built id if (list->getLastClickedId() == i) { rect(bmp_screen, (iDrawX + 1), (iDrawY + 1), (iDrawXEnd - 1), (iDrawYEnd - 1), makecol(game.fade_select, game.fade_select, game.fade_select)); rect(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, makecol(game.fade_select, game.fade_select, game.fade_select)); } } int amountToShow = item->getTimesToBuild(); if (amountToShow <= 0) { amountToShow = item->getTimesOrdered(); } if (amountToShow > 0) { // draw number of times to build this thing (queueing) int textX = iDrawX + 41; int textY = iDrawY + 16; if (amountToShow < 10) { textX += 10; } // draw alfont_textprintf(bmp_screen, game_font, textX + 1,textY + 1, makecol(0,0,0), "%d", amountToShow); alfont_textprintf(bmp_screen, game_font, textX,textY, makecol(255,255,255), "%d", amountToShow); } // draw rectangle when mouse hovers over icon if (isOverItemCoordinates_Boolean(mouse_x, mouse_y, iDrawX, iDrawY)) { int iColor=makecol(game.fade_select, game.fade_select, game.fade_select); if (player[0].getHouse() == ATREIDES) { iColor = makecol(0, 0, game.fade_select); } if (player[0].getHouse() == HARKONNEN) { iColor = makecol(game.fade_select, 0, 0); } if (player[0].getHouse() == ORDOS) { iColor = makecol(0, game.fade_select, 0); } rect(bmp_screen, (iDrawX + 1), (iDrawY + 1), (iDrawXEnd - 1), (iDrawYEnd - 1), iColor); rect(bmp_screen, iDrawX, iDrawY, iDrawXEnd, iDrawYEnd, iColor); } iDrawY+=48; } set_clip_rect(bmp_screen, 0, 0, game.screen_x, game.screen_y); }
/** * Show credits with list of contributors. * * Names of people are shown scrolling up like in movie-credits.\n * Uses map from wesnoth or campaign as background. */ void show_about(display &disp, std::string campaign) { cursor::set(cursor::WAIT); CVideo &video = disp.video(); // surface screen = video.getSurface(); // if (screen == NULL) return; std::vector<std::string> text = about::get_text(campaign); // SDL_Rect screen_rect = {0, 0, video.getx(), video.gety()}; // const surface_restorer restorer(&video, screen_rect); cursor::set(cursor::NORMAL); std::vector<shared_string> image_list; if(campaign.size() && !images[campaign].empty()){ image_list=utils::split_shared(images[campaign]); }else{ image_list=utils::split_shared(images_default,',',utils::STRIP_SPACES); } surface map_image(scale_surface(image::get_image(image_list[0]), video.getx(), video.gety())); if(! map_image){ image_list[0]=game_config::game_title; map_image=surface(scale_surface(image::get_image(image_list[0]), video.getx(), video.gety())); } gui::button close(video,_("Close")); close.set_location((video.getx()/2)-(close.width()/2), video.gety() - 30); close.set_volatile(true); const int def_size = font::SIZE_XLARGE; const SDL_Color def_color = font::NORMAL_COLOUR; //substitute in the correct control characters for '+' and '-' std::string before_header(2, ' '); before_header[0] = font::LARGE_TEXT; for(unsigned i = 0; i < text.size(); ++i) { std::string &s = text[i]; if (s.empty()) continue; char &first = s[0]; if (first == '-') first = font::SMALL_TEXT; else if (first == '+') { first = font::LARGE_TEXT; text.insert(text.begin() + i, before_header); ++i; } } text.insert(text.begin(), 10, before_header); int startline = 0; //TODO: use values proportionnal to screen ? // distance from top of map image to top of scrolling text const int top_margin = 60; // distance from bottom of scrolling text to bottom of map image const int bottom_margin = 40; // distance from left of scrolling text to the frame border const int text_left_padding = video.getx()/32; int offset = 0; bool is_new_line = true; int first_line_height = 0; SDL_Rect frame_area = { video.getx() * 3/32, top_margin, video.getx() * 13 / 16, video.gety() - top_margin - bottom_margin }; // we use a dialog to contains the text. Strange idea but at least the style // will be consistent with the titlescreen gui::dialog_frame f(video, "", gui::dialog_frame::titlescreen_style, false); // set the layout and get the interior rectangle SDL_Rect text_rect = f.layout(frame_area).interior; text_rect.x += text_left_padding; text_rect.w -= text_left_padding; // make a copy to prevent SDL_blit to change its w and h SDL_Rect text_rect_blit = text_rect; CKey key; bool last_escape; surface text_surf = create_neutral_surface(text_rect.w, text_rect.h); //create_compatible_surface(screen, text_rect.w, text_rect.h); SDL_SetAlpha(text_surf, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); int image_count = 0; int scroll_speed = 4; // scroll_speed*50 = speed of scroll in pixel per second // initialy redraw all bool redraw_mapimage = true; int max_text_width = text_rect.w; do { last_escape = key[SDLK_ESCAPE] != 0; // check to see if background image has changed if(text.size() && (image_count < ((startline * static_cast<int>(image_list.size())) / static_cast<int>(text.size())))){ image_count++; surface temp=surface(scale_surface(image::get_image(image_list[image_count]), video.getx(), video.gety())); map_image=temp?temp:map_image; redraw_mapimage = true; } // if (redraw_mapimage) { // draw map to screen, thus erasing all text //SDL_BlitSurface(map_image, NULL, screen, NULL); blit_surface(0, 0, map_image); // update_rect(screen_rect); // redraw the dialog f.draw_background(); f.draw_border(); // cache the dialog background (alpha blending + blurred map) //SDL_BlitSurface(screen, &text_rect, text_surf, NULL); redraw_mapimage = false; } /* else { // redraw the saved part of the dialog where text scrolled // thus erasing all text SDL_Rect modified = {0,0, max_text_width, text_rect.h}; SDL_BlitSurface(text_surf, &modified, screen, &text_rect_blit); //update_rect(text_rect); } */ const int line_spacing = 5; int y = text_rect.y - offset; int line = startline; int cur_line = 0; max_text_width = 0; { // clip to keep text into the frame (thus the new code block) clip_rect_setter set_clip_rect(/*screen,*/ text_rect); do { // draw the text (with ellipsis if needed) // update the max_text_width for future cleaning int w = font::draw_text(&video, text_rect, def_size, def_color, text[line], text_rect.x, y).w; max_text_width = std::max<int>(max_text_width, w); // since the real drawing on screen is clipped, // we do a dummy one to get the height of the not clipped line. // (each time because special format characters may change it) const int line_height = font::draw_text(NULL, text_rect, def_size, def_color, text[line], 0,0).h; if(is_new_line) { is_new_line = false; first_line_height = line_height + line_spacing; } line++; if(size_t(line) > text.size()-1) line = 0; y += line_height + line_spacing; cur_line++; } while(y < text_rect.y + text_rect.h); } // performs the actual scrolling offset += scroll_speed; if (offset>=first_line_height) { offset -= first_line_height; is_new_line = true; startline++; if(size_t(startline) == text.size()){ startline = 0; image_count = -1; } } // handle events if (key[SDLK_UP] && scroll_speed < 20) { ++scroll_speed; } if (key[SDLK_DOWN] && scroll_speed > 0) { --scroll_speed; } events::pump(); events::raise_process_event(); events::raise_draw_event(); // flip screen and wait, so the text does not scroll too fast disp.flip(); disp.delay(20); } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE])); }
void GameOver::update() { if(counter<254) { if(counter<=32) link.setHitTimer(32-counter); if(counter>=62 && counter<138) { switch((counter-62)%20) { case 0: link.dir=right; break; case 5: link.dir=up; break; case 10: link.dir=left; break; case 15: link.dir=down; break; } link.linkstep(); } if(counter>=194 && counter<208) { if(counter==194) link.setAction(dying); link.extend = 0; link.cs = wpnsbuf[iwDeath].csets&15; link.tile = wpnsbuf[iwDeath].tile; if(BSZ) link.tile+=(counter-194)/3; else if(counter>=204) link.tile++; } if(counter==208) link.setDontDraw(true); if(get_bit(quest_rules,qr_FADE)) { if(counter < 170) { if(counter<60) { draw_screen(tmpscr); //reuse our static subscreen set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h); blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); } if(counter==60) { red_shift(); create_rgb_table_range(&rgb_table, RAMpal, 208, 239, NULL); create_zc_trans_table(&trans_table, RAMpal, 128, 128, 128); memcpy(&trans_table2, &trans_table, sizeof(COLOR_MAP)); for(int q=0; q<PAL_SIZE; q++) { trans_table2.data[0][q] = q; trans_table2.data[q][q] = q; } } if(counter>=60 && counter<=169) { draw_screen(tmpscr); //reuse our static subscreen blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); red_shift(); } if(counter>=139 && counter<=169)//fade from red to black { fade_interpolate(RAMpal,black_palette,RAMpal, (counter-138)<<1, 224, 255); create_rgb_table_range(&rgb_table, RAMpal, 208, 239, NULL); create_zc_trans_table(&trans_table, RAMpal, 128, 128, 128); memcpy(&trans_table2, &trans_table, sizeof(COLOR_MAP)); for(int q=0; q<PAL_SIZE; q++) { trans_table2.data[0][q] = q; trans_table2.data[q][q] = q; } refreshpal=true; } } else //counter>=170 { if(counter==170)//make Link grayish { fade_interpolate(RAMpal,black_palette,RAMpal,64, 224, 255); for(int i=CSET(6); i < CSET(7); i++) { int g = (RAMpal[i].r + RAMpal[i].g + RAMpal[i].b)/3; RAMpal[i] = _RGB(g,g,g); } refreshpal = true; } //draw only link. otherwise black layers might cover him. rectfill(framebuf,0,playing_field_offset,255,167+playing_field_offset,0); link.draw(framebuf); blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); } } else //!qr_FADE { if(counter==58) { for(int i = 0; i < 96; i++) tmpscr->cset[i] = 3; for(int j=0; j<6; j++) if(tmpscr->layermap[j]>0) for(int i=0; i<96; i++) tmpscr2[j].cset[i] = 3; } if(counter==59) { for(int i = 96; i < 176; i++) tmpscr->cset[i] = 3; for(int j=0; j<6; j++) if(tmpscr->layermap[j]>0) for(int i=96; i<176; i++) tmpscr2[j].cset[i] = 3; } if(counter==60) { for(int i=0; i<176; i++) { tmpscr->cset[i] = 2; } for(int j=0; j<6; j++) if(tmpscr->layermap[j]>0) for(int i=0; i<176; i++) tmpscr2[j].cset[i] = 2; for(int i=1; i<16; i+=3) { RAMpal[CSET(2)+i] = NESpal(0x17); RAMpal[CSET(2)+i+1] = NESpal(0x16); RAMpal[CSET(2)+i+2] = NESpal(0x26); } refreshpal=true; } if(counter==139) slide_in_color(0x06); if(counter==149) slide_in_color(0x07); if(counter==159) slide_in_color(0x0F); if(counter==169) { slide_in_color(0x0F); slide_in_color(0x0F); } if(counter==170) { for(int i=1; i<16; i+=3) { RAMpal[CSET(6)+i] = NESpal(0x10); RAMpal[CSET(6)+i+1] = NESpal(0x30); RAMpal[CSET(6)+i+2] = NESpal(0x00); refreshpal = true; } } if(counter < 169) { draw_screen(tmpscr); //reuse our static subscreen blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); } else { //draw only link. otherwise black layers might cover him. rectfill(framebuf,0,playing_field_offset,255,167+playing_field_offset,0); link.draw(framebuf); blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); } } } else if(counter<350)//draw 'GAME OVER' text { clear_bitmap(framebuf); blit(subscrbmp,framebuf,0,0,0,0,256,passive_subscreen_height); textout_ex(framebuf,zfont,"GAME OVER",96,playing_field_offset+80,1,-1); } else { clear_bitmap(framebuf); } //SFX... put them all here switch(counter) { case 0: sfx(WAV_OUCH,pan(int(link.x))); break; case 60: sfx(WAV_SPIRAL); break; case 194: sfx(WAV_MSG); break; } //advanceframe(true); counter++; if(counter<353) return; finish(); destroy_bitmap(subscrbmp); link.setAction(none); link.setDontDraw(false); }
void BasicEditboxView::draw() { rectfill(dbuf, 0, 0, host->w, host->h, bgcolor); set_clip_rect(dbuf, area_xstart-host->x, area_ystart-host->y, area_xstart-host->x+area_width-1, area_ystart-host->y+area_height-1); int textheight = text_height(textfont); int y = -view_y; for(list<LineData>::iterator it = model->getLines().begin(); it != model->getLines().end(); it++) { if(y >= area_ystart-host->y-textheight && y <= area_ystart+host->y + area_height) blit((*it).strip, dbuf, 0, 0, area_xstart-host->x-view_x, area_ystart-host->y+y, view_width, textheight); y+=textheight; } set_clip_rect(dbuf, 0,0,host->w,host->h); //draw cursor if(model->getCursor().isVisible()) { CursorPos cp = model->findCursor(); //int textheight = text_height(textfont); int cursory = cp.lineno*text_height(textfont); //GAH, too many damn coordinate offsets :-/ vline(dbuf, area_xstart-host->x+cp.x-view_x-1, area_ystart-host->y+cursory-view_y-1, area_ystart-host->y+cursory-view_y+textheight, fgcolor); } //draw selection set_clip_rect(dbuf, area_xstart-host->x, area_ystart-host->y, area_xstart-host->x+area_width-1, area_ystart-host->y+area_height-1); if(model->getSelection().hasSelection()) { pair<int, int> selection = model->getSelection().getSelection(); CursorPos selstart = model->findIndex(selection.first); CursorPos selend = model->findIndex(selection.second); if(selstart.lineno == selend.lineno) { //invert the selection rectangle int starty = area_ystart-host->y-view_y+selstart.lineno*textheight; int startx = area_xstart-host->x+selstart.x-view_x; int endx = area_xstart-host->x+selend.x-view_x; invertRectangle(startx, starty, endx, starty+textheight); } else { //do the starting line int starty = area_ystart-host->y-view_y + selstart.lineno*textheight; int startx = area_xstart-host->x+selstart.x-view_x; int endx; if(hstyle == HSTYLE_EOLINE) { endx= area_xstart-host->x+area_width-view_x; } else { endx = area_xstart-host->x+selstart.it->strip->w-view_x; } invertRectangle(startx,starty,endx,starty+textheight); //do intermediate lines list<LineData>::iterator it = selstart.it; it++; for(int line = selstart.lineno+1; line < selend.lineno; line++,it++) { int endx2; if(hstyle == HSTYLE_EOLINE) { endx2=area_xstart-host->x+area_width-view_x; } else { endx2 = area_xstart-host->x+it->strip->w-view_x; } invertRectangle(area_xstart-host->x-view_x, area_ystart-host->y-view_y+line*textheight, endx2, area_ystart-host->y-view_y+(line+1)*textheight); } //do the last line endx = area_xstart-host->x+selend.x-view_x; invertRectangle(area_xstart-host->x-view_x,area_ystart-host->y-view_y+selend.lineno*textheight, endx, area_ystart-host->y-view_y+(selend.lineno+1)*textheight); } } set_clip_rect(dbuf, 0,0,host->w,host->h); drawExtraComponents(); vsync(); blit(dbuf, screen, 0, 0, host->x, host->y,host->w, host->h); set_clip_rect(screen, 0, 0,SCREEN_W,SCREEN_H); Backend::graphics->waitTick(); Backend::graphics->showBackBuffer(); }
void gks_drv_mac( int fctid, int dx, int dy, int dimx, int *ia, int lr1, double *r1, int lr2, double *r2, int lc, char *chars, void **ptr) { p = (ws_state_list *) *ptr; switch (fctid) { /* open workstation */ case 2: gkss = (gks_state_list_t *) *ptr; p = (ws_state_list *) calloc(1, sizeof(ws_state_list)); if (pthread_mutex_init(&p->mutex, NULL)) { perror("pthread_mutex_init"); exit(-1); } p->run = 0; if (pthread_create(&p->thread, NULL, exec, (void *) p)) { perror("pthread_create"); exit(-1); } while (!p->run) usleep(10000); p->port = GetWindowPort(p->win); SetPort(p->port); *ptr = p; break; /* close workstation */ case 3: p->run = 0; pthread_join(p->thread, NULL); pthread_mutex_destroy(&p->mutex); free(p); break; /* activate workstation */ case 4: p->state = GKS_K_WS_ACTIVE; break; /* deactivate workstation */ case 5: p->state = GKS_K_WS_INACTIVE; break; /* clear workstation */ case 6: clear_ws(); break; /* update workstation */ case 8: pthread_mutex_lock(&p->mutex); QDFlushPortBuffer(p->port, NULL); pthread_mutex_unlock(&p->mutex); break; /* polyline */ case 12: if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); LockPortBits(p->port); polyline(ia[0], r1, r2); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* polymarker */ case 13: if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); LockPortBits(p->port); polymarker(ia[0], r1, r2); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* text */ case 14: if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); LockPortBits(p->port); text(r1[0], r2[0], strlen(chars), chars); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* fill area */ case 15: if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); LockPortBits(p->port); fillarea(ia[0], r1, r2); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* cell array */ case 16: case DRAW_IMAGE: if (p->state == GKS_K_WS_ACTIVE) { int true_color = fctid == DRAW_IMAGE; pthread_mutex_lock(&p->mutex); LockPortBits(p->port); cellarray(r1[0], r1[1], r2[0], r2[1], dx, dy, dimx, ia, true_color); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* set color representation */ case 48: set_color_rep(ia[1], r1[0], r1[1], r1[2]); break; case 49: /* set window */ set_norm_xform(*ia, gkss->window[*ia], gkss->viewport[*ia]); break; case 50: /* set viewport */ set_norm_xform(*ia, gkss->window[*ia], gkss->viewport[*ia]); if (*ia == gkss->cntnr) set_clip_rect(*ia); break; case 52: /* select normalization transformation */ case 53: /* set clipping inidicator */ set_clip_rect(gkss->cntnr); break; /* set workstation window */ case 54: p->window[0] = r1[0]; p->window[1] = r1[1]; p->window[2] = r2[0]; p->window[3] = r2[1]; set_xform(); init_norm_xform(); break; /* set workstation viewport */ case 55: p->viewport[0] = r1[0]; p->viewport[1] = r1[1]; p->viewport[2] = r2[0]; p->viewport[3] = r2[1]; if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); LockPortBits(p->port); resize_window(); set_xform(); init_norm_xform(); UnlockPortBits(p->port); pthread_mutex_unlock(&p->mutex); } break; /* request locator */ case 81: if (p->state == GKS_K_WS_ACTIVE) { pthread_mutex_lock(&p->mutex); QDFlushPortBuffer(p->port, NULL); get_pointer(r1, r2, &ia[0]); pthread_mutex_unlock(&p->mutex); } break; default: ; } }