Control: Change controls to use new callback infrastrucure.
[gemrb.git] / gemrb / core / Video.cpp
blobbcd600146eead9ebf825dd3682ff879effc42a7c
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.
21 #include "Video.h"
23 #include "win32def.h"
25 #include "Audio.h"
26 #include "Interface.h"
27 #include "Palette.h"
29 #include <cmath>
31 const TypeID Video::ID = { "Video" };
33 Video::Video(void)
35 Evnt = NULL;
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));
44 Video::~Video(void)
48 /** Set Event Manager */
49 void Video::SetEventMgr(EventMgr* evnt)
51 //if 'evnt' is NULL then no Event Manager will be used
52 Evnt = evnt;
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)
64 if (grayed) {
65 DisableMouse |= MOUSE_GRAYED;
66 } else {
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)
86 if (!sprite)
87 return 0;
89 unsigned int *pixels = (unsigned int *) malloc (sprite->Width * sprite->Height * 4);
90 int i=0;
91 for (int y = 0; y < sprite->Height; y++) {
92 for (int x = 0; x < sprite->Width; x++) {
93 int sum = 0;
94 int cnt = 0;
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;
101 cnt++;
102 if (sprite->IsPixelTransparent(xx, yy))
103 sum++;
106 int tmp=255 - (sum * 255 / cnt);
107 tmp = tmp * tmp / 255;
108 pixels[i++]=tmp;
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 );
121 int i = 0;
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;
137 return small;
140 Sprite2D* Video::CreateLight(int radius, int intensity)
142 if(!radius) return NULL;
143 Point p, q;
144 int a;
145 void* pixels = malloc( radius * radius * 4 * 4);
146 int i = 0;
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;
152 if(a<0) a=0;
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;
164 return light;
167 Color Video::SpriteGetPixelSum(const Sprite2D* sprite, unsigned short xbase, unsigned short ybase, unsigned int ratio)
169 Color sum;
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];
188 return sum;
191 //Viewport specific
192 Region Video::GetViewport()
194 return Viewport;
197 void Video::SetViewport(int x, int y, unsigned int w, unsigned int h)
199 if (x>width)
200 x=width;
201 xCorr = x;
202 if (y>height)
203 y=height;
204 yCorr = y;
205 if (w>(unsigned int) width)
206 w=0;
207 Viewport.w = w;
208 if (h>(unsigned int) height)
209 h=0;
210 Viewport.h = h;
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)
217 + height / 2 );
218 Viewport.x = x;
219 Viewport.y = y;