aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/gfx/osystem/render_ticket.cpp
blob: 23cf5c318ef64a21eb7eeeb204d49b94ec0887c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

/*
 * This file is based on WME Lite.
 * http://dead-code.org/redir.php?target=wmelite
 * Copyright (c) 2011 Jan Nedoma
 */


#include "engines/wintermute/base/gfx/osystem/render_ticket.h"
#include "engines/wintermute/graphics/transform_tools.h"
#include "common/textconsole.h"

namespace Wintermute {

RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct transform) :
	_owner(owner),
	_srcRect(*srcRect),
	_dstRect(*dstRect),
	_drawNum(0),
	_isValid(true),
	_wantsDraw(true),
	_transform(transform) {
	_batchNum = 0;
	if (surf) {
		_surface = new Graphics::Surface();
		_surface->create((uint16)srcRect->width(), (uint16)srcRect->height(), surf->format);
		assert(_surface->format.bytesPerPixel == 4);
		// Get a clipped copy of the surface
		for (int i = 0; i < _surface->h; i++) {
			memcpy(_surface->getBasePtr(0, i), surf->getBasePtr(srcRect->left, srcRect->top + i), srcRect->width() * _surface->format.bytesPerPixel);
		}
		// Then scale it if necessary
		if (_transform._angle != 0) {
			TransparentSurface src(*_surface, false);
			Common::Rect srcRect_1(srcRect->left, srcRect->top, srcRect->right, srcRect->bottom);
			Graphics::Surface *temp = src.rotate(srcRect_1, transform);
			_surface->free();
			delete _surface;
			_surface = temp;
		} else if (dstRect->width() != srcRect->width() || dstRect->height() != srcRect->height()) { 
			TransparentSurface src(*_surface, false);
			Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
			_surface->free();
			delete _surface;
			_surface = temp;
		}
	} else {
		_surface = nullptr;
		
		if (transform._angle != 0) { // Make sure comparison-tickets get the correct width
			Rect32 dstRect;
			Point32 newHotspot;
			dstRect = TransformTools::newRect(_srcRect, transform,  &newHotspot);
			_dstRect.setWidth(dstRect.right-dstRect.left);
			_dstRect.setHeight(dstRect.bottom-dstRect.top);
		}
	}
}

RenderTicket::~RenderTicket() {
	if (_surface) {
		_surface->free();
		delete _surface;
	}
}

bool RenderTicket::operator==(const RenderTicket &t) const {
	if ((t._owner != _owner) ||
		(t._batchNum != _batchNum) ||
		(t._transform != _transform)  || 
		(t._dstRect != _dstRect) ||
		(t._srcRect != _srcRect) 
	) {
		return false;
	}
	return true;
}

// Replacement for SDL2's SDL_RenderCopy
void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
	TransparentSurface src(*getSurface(), false);

	Common::Rect clipRect;
	clipRect.setWidth(getSurface()->w);
	clipRect.setHeight(getSurface()->h);

	src._enableAlphaBlit = !_transform._alphaDisable;
	src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}

void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
	TransparentSurface src(*getSurface(), false);
	bool doDelete = false;
	if (!clipRect) {
		doDelete = true;
		clipRect = new Common::Rect();
		clipRect->setWidth(getSurface()->w);
		clipRect->setHeight(getSurface()->h);
	}

	src._enableAlphaBlit = !_transform._alphaDisable; 
	src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
	if (doDelete) {
		delete clipRect;
	}
}

} // end of namespace Wintermute