1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include "Interface.h"
31 const TypeID
Video::ID
= { "Video" };
37 // Initialize gamma correction tables
38 for (int i
= 0; i
< 256; i
++) {
39 Gamma22toGamma10
[i
] = (unsigned char)(0.5 + (pow (i
/255.0, 2.2/1.0) * 255.0));
40 Gamma10toGamma22
[i
] = (unsigned char)(0.5 + (pow (i
/255.0, 1.0/2.2) * 255.0));
48 /** Set Event Manager */
49 void Video::SetEventMgr(EventMgr
* evnt
)
51 //if 'evnt' is NULL then no Event Manager will be used
55 /** Mouse is invisible and cannot interact */
56 void Video::SetMouseEnabled(int enabled
)
58 DisableMouse
= enabled
^MOUSE_DISABLED
;
61 /** Mouse cursor is grayed and doesn't click (but visible and movable) */
62 void Video::SetMouseGrayed(bool grayed
)
65 DisableMouse
|= MOUSE_GRAYED
;
67 DisableMouse
&= ~MOUSE_GRAYED
;
71 void Video::BlitTiled(Region rgn
, const Sprite2D
* img
, bool anchor
)
73 int xrep
= ( rgn
.w
+ img
->Width
- 1 ) / img
->Width
;
74 int yrep
= ( rgn
.h
+ img
->Height
- 1 ) / img
->Height
;
75 for (int y
= 0; y
< yrep
; y
++) {
76 for (int x
= 0; x
< xrep
; x
++) {
77 BlitSprite(img
, rgn
.x
+ (x
*img
->Width
),
78 rgn
.y
+ (y
*img
->Height
), anchor
, &rgn
);
83 //Sprite conversion, creation
84 Sprite2D
* Video::CreateAlpha( const Sprite2D
*sprite
)
89 unsigned int *pixels
= (unsigned int *) malloc (sprite
->Width
* sprite
->Height
* 4);
91 for (int y
= 0; y
< sprite
->Height
; y
++) {
92 for (int x
= 0; x
< sprite
->Width
; x
++) {
95 for (int xx
=x
-3;xx
<=x
+3;xx
++) {
96 for(int yy
=y
-3;yy
<=y
+3;yy
++) {
97 if (((xx
==x
-3) || (xx
==x
+3)) &&
98 ((yy
==y
-3) || (yy
==y
+3))) continue;
99 if (xx
< 0 || xx
>= sprite
->Width
) continue;
100 if (yy
< 0 || yy
>= sprite
->Height
) continue;
102 if (sprite
->IsPixelTransparent(xx
, yy
))
106 int tmp
=255 - (sum
* 255 / cnt
);
107 tmp
= tmp
* tmp
/ 255;
111 return CreateSprite( sprite
->Width
, sprite
->Height
, 32, 0xFF000000,
112 0x00FF0000, 0x0000FF00, 0x000000FF, pixels
);
115 Sprite2D
* Video::SpriteScaleDown( const Sprite2D
* sprite
, unsigned int ratio
)
117 unsigned int Width
= sprite
->Width
/ ratio
;
118 unsigned int Height
= sprite
->Height
/ ratio
;
120 unsigned int* pixels
= (unsigned int *) malloc( Width
* Height
* 4 );
123 for (unsigned int y
= 0; y
< Height
; y
++) {
124 for (unsigned int x
= 0; x
< Width
; x
++) {
125 Color c
= SpriteGetPixelSum( sprite
, x
, y
, ratio
);
127 *(pixels
+ i
++) = c
.r
+ (c
.g
<< 8) + (c
.b
<< 16) + (c
.a
<< 24);
131 Sprite2D
* small
= CreateSprite( Width
, Height
, 32, 0x000000ff, 0x0000ff00, 0x00ff0000,
132 0xff000000, pixels
, false, 0 );
134 small
->XPos
= sprite
->XPos
/ ratio
;
135 small
->YPos
= sprite
->YPos
/ ratio
;
140 Sprite2D
* Video::CreateLight(int radius
, int intensity
)
142 if(!radius
) return NULL
;
145 void* pixels
= malloc( radius
* radius
* 4 * 4);
148 for (p
.y
= -radius
; p
.y
< radius
; p
.y
++) {
149 for (p
.x
= -radius
; p
.x
< radius
; p
.x
++) {
150 a
= intensity
*(radius
-(signed) Distance(p
,q
))/radius
;
153 else if(a
>255) a
= 255;
155 *((unsigned int*)pixels
+ i
++) = 0xffffff + ((a
/2) << 24);
159 Sprite2D
* light
= CreateSprite( radius
*2, radius
*2, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, pixels
);
161 light
->XPos
= radius
;
162 light
->YPos
= radius
;
167 Color
Video::SpriteGetPixelSum(const Sprite2D
* sprite
, unsigned short xbase
, unsigned short ybase
, unsigned int ratio
)
170 unsigned int count
= ratio
*ratio
;
171 unsigned int r
=0, g
=0, b
=0, a
=0;
173 for (unsigned int x
= 0; x
< ratio
; x
++) {
174 for (unsigned int y
= 0; y
< ratio
; y
++) {
175 Color c
= sprite
->GetPixel( xbase
*ratio
+x
, ybase
*ratio
+y
);
176 r
+= Gamma22toGamma10
[c
.r
];
177 g
+= Gamma22toGamma10
[c
.g
];
178 b
+= Gamma22toGamma10
[c
.b
];
179 a
+= Gamma22toGamma10
[c
.a
];
183 sum
.r
= Gamma10toGamma22
[r
/ count
];
184 sum
.g
= Gamma10toGamma22
[g
/ count
];
185 sum
.b
= Gamma10toGamma22
[b
/ count
];
186 sum
.a
= Gamma10toGamma22
[a
/ count
];
192 Region
Video::GetViewport()
197 void Video::SetViewport(int x
, int y
, unsigned int w
, unsigned int h
)
205 if (w
>(unsigned int) width
)
208 if (h
>(unsigned int) height
)
213 void Video::MoveViewportTo(int x
, int y
)
215 if (x
!= Viewport
.x
|| y
!= Viewport
.y
) {
216 core
->GetAudioDrv()->UpdateListenerPos( (x
- xCorr
) + width
/ 2, (y
- yCorr
)