Files
scummvm-cursorfix/engines/wintermute/base/gfx/osystem/base_render_osystem.h
2026-02-02 04:50:13 +01:00

156 lines
5.4 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_RENDERER_SDL_H
#define WINTERMUTE_BASE_RENDERER_SDL_H
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "common/rect.h"
#include "common/list.h"
#include "graphics/managed_surface.h"
#include "graphics/transform_struct.h"
namespace Wintermute {
class BaseSurfaceOSystem;
class RenderTicket;
/**
* A 2D-renderer implementation for WME.
* This renderer makes use of a "ticket"-system, where all draw-calls
* are stored as tickets until flip() is called, and compared against the tickets
* from last frame, to determine which calls were the same as last round
* (i.e. in the exact same order, with the exact same arguments), and thus
* figure out which parts of the screen need to be redrawn.
*
* Important concepts to handle here, is the ordered number of any ticket
* which is called the "drawNum", every frame this starts from scratch, and
* then the incoming tickets created from the draw-calls are checked to see whether
* they came before, on, or after the drawNum they had last frame. Everything else
* being equal, this information is then used to check whether the draw order changed,
* which will then create a need for redrawing, as we draw with an alpha-channel here.
*
* There is also a draw path that draws without tickets, for debugging purposes,
* as well as to accommodate situations with large enough amounts of draw calls,
* that there will be too much overhead involved with comparing the generated tickets.
*/
class BaseRenderOSystem : public BaseRenderer {
public:
BaseRenderOSystem(BaseGame *inGame);
~BaseRenderOSystem() override;
typedef Common::List<RenderTicket *>::iterator RenderQueueIterator;
Common::String getName() const override;
bool initRenderer(int width, int height, bool windowed) override;
bool flip() override;
bool indicatorFlip(int32 x, int32 y, int32 width, int32 height) override;
bool forcedFlip() override;
bool clear() override;
Graphics::PixelFormat getPixelFormat() const override;
bool fade(uint16 alpha) override;
bool fadeToColor(byte r, byte g, byte b, byte a) override;
bool drawLine(int x1, int y1, int x2, int y2, uint32 color) override;
bool fillRect(int x, int y, int w, int h, uint32 color) override;
BaseImage *takeScreenshot(int newWidth = 0, int newHeight = 0) override;
void onWindowChange() override;
void setWindowed(bool windowed) override;
void invalidateTicket(RenderTicket *renderTicket);
void invalidateTicketsFromSurface(BaseSurfaceOSystem *surf);
/**
* Insert a new ticket into the queue, adding a dirty rect
* @param renderTicket the ticket to be added.
*/
void drawFromTicket(RenderTicket *renderTicket);
/**
* Re-insert an existing ticket into the queue, adding a dirty rect
* out-of-order from last draw from the ticket.
* @param ticket iterator pointing to the ticket to be added.
*/
void drawFromQueuedTicket(const RenderQueueIterator &ticket);
bool setViewport(int left, int top, int right, int bottom) override;
bool setViewport(Common::Rect32 *rect) override { return BaseRenderer::setViewport(rect); }
void modTargetRect(Common::Rect *rect);
void pointFromScreen(Common::Point32 *point);
void pointToScreen(Common::Point32 *point);
float getScaleRatioX() const override {
return _ratioX;
}
float getScaleRatioY() const override {
return _ratioY;
}
bool startSpriteBatch() override;
bool endSpriteBatch() override;
void endSaveLoad() override;
void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Graphics::TransformStruct &transform);
BaseSurface *createSurface() override;
private:
/**
* Mark a specified rect of the screen as dirty.
* @param rect the region to be marked as dirty
*/
void addDirtyRect(const Common::Rect &rect);
/**
* Traverse the tickets that are dirty, and draw them
*/
void drawTickets();
// Non-dirty-rects:
void drawFromSurface(RenderTicket *ticket);
// Dirty-rects:
void drawFromSurface(RenderTicket *ticket, Common::Rect *dstRect, Common::Rect *clipRect);
Common::Rect *_dirtyRect;
Common::List<RenderTicket *> _renderQueue;
bool _needsFlip;
RenderQueueIterator _lastFrameIter;
Common::Rect _renderRect;
Graphics::ManagedSurface *_renderSurface;
int _borderLeft;
int _borderTop;
int _borderRight;
int _borderBottom;
bool _disableDirtyRects;
float _ratioX;
float _ratioY;
uint32 _clearColor;
bool _skipThisFrame;
int _lastScreenChangeID; // previous value of OSystem::getScreenChangeID()
};
} // End of namespace Wintermute
#endif