static bool build_map_preview(std::ostringstream& ostream) { SDL_Rect r = {0, 0, RENDER_WIDTH, RENDER_HEIGHT}; SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, r.w, r.h, 32, 0xff0000, 0x00ff00, 0x0000ff, 0); if (!surface) return false; SDL_FillRect(surface, &r, SDL_MapRGB(surface->format, 0, 0, 0)); struct overhead_map_data overhead_data; overhead_data.half_width = r.w >> 1; overhead_data.half_height = r.h >> 1; overhead_data.width = r.w; overhead_data.height = r.h; overhead_data.top = overhead_data.left = 0; overhead_data.scale = RENDER_SCALE; overhead_data.mode = _rendering_saved_game_preview; overhead_data.origin.x = local_player->location.x; overhead_data.origin.y = local_player->location.y; bool old_OGL_MapActive = OGL_MapActive; _set_port_to_custom(surface); OGL_MapActive = false; _render_overhead_map(&overhead_data); OGL_MapActive = old_OGL_MapActive; _restore_port(); SDL_RWops *rwops = SDL_RWFromOStream(ostream); #if defined(HAVE_PNG) && defined(HAVE_SDL_IMAGE_H) int ret = IMG_SavePNG_RW(rwops, surface, IMG_COMPRESS_DEFAULT, NULL, 0); #else int ret = SDL_SaveBMP_RW(surface, rwops, false); #endif SDL_FreeSurface(surface); SDL_RWclose(rwops); return (ret == 0); }
/* ------------ Local code */ static void add_overhead_thumbnail( FileSpecifier &File) { PicHandle picture; PicHandle preview; RgnHandle clip_region; FontInfo info; short text_x, text_y; short text_length; Str255 temporary; GWorldPtr old_gworld; GDHandle old_device; struct overhead_map_data overhead_data; Rect bounds; AEDesc aeFileSpec; FSSpec *SpecPtr; // Skip all this if there's no nav services to install the preview if(!machine_has_nav_services() || NavLibraryVersion() < kNavServicesVersion_2_0) return; GetGWorld(&old_gworld, &old_device); SetGWorld(world_pixels, (GDHandle) NULL); // Note well. We're using world_pixels to create our thumbnail pict within. // If world_pixels is runing as a postage stamp (low-res + small display space) // Then it is actually smaller than the size we're looking to build a thumbnail // within. But seeing as we're generating pict images and using drawing commands // instead of bit-wise operations. It all works out. /* Create the bounding rectangle */ SetRect(&bounds, 0, 0, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT); /* Start recording.. */ picture= OpenPicture(&bounds); PaintRect(&bounds); overhead_data.scale= OVERHEAD_MAP_MINIMUM_SCALE; overhead_data.origin.x= local_player->location.x; overhead_data.origin.y= local_player->location.y; overhead_data.half_width= RECTANGLE_WIDTH(&bounds)/2; overhead_data.half_height= RECTANGLE_HEIGHT(&bounds)/2; overhead_data.width= RECTANGLE_WIDTH(&bounds); overhead_data.height= RECTANGLE_HEIGHT(&bounds); overhead_data.mode= _rendering_saved_game_preview; _render_overhead_map(&overhead_data); RGBForeColor(&rgb_black); PenSize(1, 1); TextFont(0); TextFace(normal); TextSize(0); ClosePicture(); // JTP: Add Nav Services style preview SetRect(&bounds, 0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); preview= OpenPicture(&bounds); SetRect(&bounds, PREVIEW_IMAGE_X, PREVIEW_IMAGE_Y, THUMBNAIL_WIDTH + PREVIEW_IMAGE_X, THUMBNAIL_HEIGHT + PREVIEW_IMAGE_Y); clip_region= NewRgn(); GetClip(clip_region); ClipRect(&bounds); DrawPicture(picture, &bounds); SetClip(clip_region); /* Center the text in the rectangle */ // LP: Classic doesn't have this function #ifdef TARGET_API_MAC_CARBON CopyCStringToPascal(static_world->level_name, temporary); #else strncpy((char *)temporary,static_world->level_name,LEVEL_NAME_LENGTH); c2pstr((char *)temporary); #endif // LP: fix to allow lengths more than 127 bytes (not really necessary, but...) text_length = *ptemporary; TruncText(PREVIEW_WIDTH, (char *)temporary+1, &text_length, smTruncEnd); *ptemporary = text_length; GetFontInfo(&info); text_y= PREVIEW_HEIGHT - info.descent; text_x= PREVIEW_LABEL_X + (PREVIEW_WIDTH-StringWidth(temporary))/2; MoveTo(text_x, text_y); DrawString(temporary); ClosePicture(); // This requires NavServices 2.0, what's the inline check? // From FSS get a AEDesc OSStatus err; SpecPtr = &File.GetSpec(); err = AECreateDesc(typeFSS, SpecPtr, sizeof(FSSpec), &aeFileSpec); HLock((Handle)preview); err = NavCreatePreview(&aeFileSpec, 'PICT', *preview, GetHandleSize((Handle)preview)); HUnlock((Handle)preview); AEDisposeDesc(&aeFileSpec); KillPicture(preview); KillPicture(picture); DisposeRgn(clip_region); SetGWorld(old_gworld, old_device); }