void Scene::refreshBackground(int xAmount, int yAmount) { if (_globals->_sceneManager._scene->_activeScreenNumber == -1) return; // Set the quadrant ranges int xHalfCount = MIN(_backSurface.getBounds().width() / 160, _backgroundBounds.width() / 160); int yHalfCount = MIN(_backSurface.getBounds().height() / 100, _backgroundBounds.height() / 100); int xHalfOffset = (_backgroundBounds.width() / 160) == 3 ? 0 : _sceneBounds.left / 160; int yHalfOffset = (_backgroundBounds.height() / 100) == 3 ? 0 : _sceneBounds.top / 100; // Set the limits and increment amounts int xInc = (xAmount < 0) ? -1 : 1; int xSectionStart = (xAmount < 0) ? 15 : 0; int xSectionEnd = (xAmount < 0) ? -1 : 16; int yInc = (yAmount < 0) ? -1 : 1; int ySectionStart = (yAmount < 0) ? 15 : 0; int ySectionEnd = (yAmount < 0) ? -1 : 16; bool changedFlag = false; for (int yp = ySectionStart; yp != ySectionEnd; yp += yInc) { for (int xp = xSectionStart; xp != xSectionEnd; xp += xInc) { if ((yp < yHalfOffset) || (yp >= (yHalfOffset + yHalfCount)) || (xp < xHalfOffset) || (xp >= (xHalfOffset + xHalfCount))) { // Flag section as enabled _enabledSections[xp * 16 + yp] = 0xffff; } else { // Check if the section is already loaded if ((_enabledSections[xp * 16 + yp] == 0xffff) || ((xAmount == 0) && (yAmount == 0))) { // Chunk isn't loaded, so load it in Graphics::Surface s = _backSurface.lockSurface(); GfxSurface::loadScreenSection(s, xp - xHalfOffset, yp - yHalfOffset, xp, yp); _backSurface.unlockSurface(); changedFlag = true; } else { int yv = (_enabledSections[xp * 16 + yp] == ((xp - xHalfOffset) << 4)) ? 0 : 1; if (yv | (yp - yHalfOffset)) { // Copy an existing 160x100 screen section previously loaded int xSectionDest = xp - xHalfOffset; int ySectionDest = yp - yHalfOffset; int xSectionSrc = _enabledSections[xp * 16 + yp] >> 4; int ySectionSrc = _enabledSections[xp * 16 + yp] & 0xf; Rect srcBounds(xSectionSrc * 160, ySectionSrc * 100, (xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100); Rect destBounds(xSectionDest * 160, ySectionDest * 100, (xSectionDest + 1) * 160, (ySectionDest + 1) * 100); _backSurface.copyFrom(_backSurface, srcBounds, destBounds); } } _enabledSections[xp * 16 + yp] = ((xp - xHalfOffset) << 4) | (yp - yHalfOffset); } } }
void convert_image_to_surface(const Image* image, const Palette* palette, she::Surface* surface, int src_x, int src_y, int dst_x, int dst_y, int w, int h) { gfx::Rect srcBounds(src_x, src_y, w, h); srcBounds = srcBounds.createIntersect(image->bounds()); if (srcBounds.isEmpty()) return; src_x = srcBounds.x; src_y = srcBounds.y; w = srcBounds.w; h = srcBounds.h; gfx::Rect dstBounds(dst_x, dst_y, w, h); dstBounds = dstBounds.createIntersect(surface->getClipBounds()); if (dstBounds.isEmpty()) return; src_x += dstBounds.x - dst_x; src_y += dstBounds.y - dst_y; dst_x = dstBounds.x; dst_y = dstBounds.y; w = dstBounds.w; h = dstBounds.h; she::ScopedSurfaceLock dst(surface); she::SurfaceFormatData fd; dst->getFormat(&fd); switch (image->pixelFormat()) { case IMAGE_RGB: convert_image_to_surface_selector<RgbTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd); break; case IMAGE_GRAYSCALE: convert_image_to_surface_selector<GrayscaleTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd); break; case IMAGE_INDEXED: convert_image_to_surface_selector<IndexedTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd); break; case IMAGE_BITMAP: convert_image_to_surface_selector<BitmapTraits>(image, dst, src_x, src_y, dst_x, dst_y, w, h, palette, &fd); break; default: ASSERT(false); throw std::runtime_error("conversion not supported"); } }
void View::onRefresh(RectList *rects, M4Surface *destSurface) { assert(destSurface); if (rects == NULL) // No rect list specified, so copy entire surface copyTo(destSurface, _coords.left, _coords.top, _transparent ? 0 : -1); else { // Loop through the set of specified rectangles RectList::iterator i; for (i = rects->begin(); i != rects->end(); ++i) { Common::Rect &destRect = *i; Common::Rect srcBounds(destRect.left - _coords.left, destRect.top - _coords.top, destRect.right - _coords.left, destRect.bottom - _coords.top); copyTo(destSurface, srcBounds, destRect.left, destRect.top, _transparent ? 0 : -1); } } }