1 // BlinkenSisters - Hunt for the Lost Pixels
2 // Bringing back the fun of the 80s
3 //
4 // (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
5 //
6 // See License.txt for licensing information
7 //
8
9
10 #include "globals.h"
11 #include "bsscreen.h"
12 #include "SDL_rotozoom.h"
13
14 Uint32 realRes_X = 0;
15 Uint32 realRes_Y = 0;
16 SDL_Surface *realRes_gScreen = 0;
17 bool realRes_enabled = false;
18 bool realRes_smoothieZoom = false;
19
20 COLOR3D colormode = COLOR3D_NONE;
21 SDL_Surface *gScreen_Left = 0;
22 SDL_Surface *gScreen_Right = 0;
23 SDL_Surface *gScreen_Normal = 0;
24 bool useColor3D = false;
25 bool enableColor3D = false;
26
BS_SetRealResolution(Uint32 width,Uint32 height,bool smoothieZoom)27 void BS_SetRealResolution(Uint32 width, Uint32 height, bool smoothieZoom) {
28 /* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order,
29 as expected by OpenGL for textures */
30 Uint32 rmask, gmask, bmask, amask;
31
32 if(width == SCR_WIDTH && height == SCR_HEIGHT) {
33 return;
34 }
35
36 /* SDL interprets each pixel as a 32-bit number, so our masks must depend
37 on the endianness (byte order) of the machine */
38 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
39 rmask = 0xff000000;
40 gmask = 0x00ff0000;
41 bmask = 0x0000ff00;
42 amask = 0x000000ff;
43 #else
44 rmask = 0x000000ff;
45 gmask = 0x0000ff00;
46 bmask = 0x00ff0000;
47 amask = 0xff000000;
48 #endif
49
50
51 realRes_X = width;
52 realRes_Y = height;
53 if(realRes_gScreen) {
54 SDL_FreeSurface(gScreen);
55 }
56
57 SDL_Surface *temp = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
58 gScreen = SDL_DisplayFormat(temp);
59 SDL_FreeSurface(temp);
60
61
62 realRes_enabled = true;
63 realRes_smoothieZoom = smoothieZoom;
64 }
65
BS_Set3DMode(COLOR3D mode)66 void BS_Set3DMode(COLOR3D mode) {
67 //bool oldState = useColor3D;
68 if(mode == COLOR3D_NONE) {
69 gScreen = gScreen_Normal;
70 useColor3D = false;
71 } else if(mode == COLOR3D_LEFT) {
72 gScreen = gScreen_Left;
73 useColor3D = true;
74 } else {
75 gScreen = gScreen_Right;
76 useColor3D = true;
77 }
78
79 /* Don't need this?
80 if(useColor3D == false && oldState == true) {
81 BS_ColorSurfacesToScreen();
82 }
83 */
84 }
85
BS_ColorSurfacesToScreen()86 void BS_ColorSurfacesToScreen() {
87
88 Uint32 pitch_n = gScreen_Normal->pitch / 4;
89 Uint32 pitch_l = gScreen_Left->pitch / 4;
90 Uint32 pitch_r = gScreen_Right->pitch / 4;
91 Uint32 i, j;
92 Uint32 pixel_l, pixel_r, pixel_n;
93
94 if (SDL_MUSTLOCK(gScreen_Normal))
95 if (SDL_LockSurface(gScreen_Normal) < 0)
96 return;
97 if (SDL_MUSTLOCK(gScreen_Left))
98 if (SDL_LockSurface(gScreen_Left) < 0)
99 return;
100 if (SDL_MUSTLOCK(gScreen_Right))
101 if (SDL_LockSurface(gScreen_Right) < 0)
102 return;
103
104 for(i=0; i < SCR_WIDTH; i++) {
105 for(j=0; j < SCR_HEIGHT; j++) {
106 pixel_l = ((Uint32 *)gScreen_Left->pixels)[j * pitch_l + i];
107 pixel_r = ((Uint32 *)gScreen_Right->pixels)[j * pitch_r + i];
108
109 pixel_l = ((pixel_l & 0xff) +
110 ((pixel_l / 256) & 0xff) +
111 ((pixel_l / 65536) & 0xff)) / 3;
112 if(pixel_l > 255) {
113 pixel_l = 255;
114 }
115 pixel_r = ((pixel_r & 0xff) +
116 ((pixel_r / 256) & 0xff) +
117 ((pixel_r / 65536) & 0xff)) / 3;
118 if(pixel_r > 255) {
119 pixel_r = 255;
120 }
121
122 //pixel_n = pixel_r * 256 + pixel_r + pixel_l * 65536;
123 pixel_n = pixel_l * 256 + pixel_l + pixel_r * 65536;
124
125 ((Uint32 *)gScreen_Normal->pixels)[j * pitch_n + i] = pixel_n;
126 }
127 }
128
129 if (SDL_MUSTLOCK(gScreen_Normal))
130 SDL_UnlockSurface(gScreen_Normal);
131 if (SDL_MUSTLOCK(gScreen_Left))
132 SDL_UnlockSurface(gScreen_Left);
133 if (SDL_MUSTLOCK(gScreen_Right))
134 SDL_UnlockSurface(gScreen_Right);
135 }
136
BS_ColorToGreyscale()137 void BS_ColorToGreyscale() {
138
139 Uint32 pitch = gScreen->pitch / 4;
140 Uint32 i, j;
141 Uint32 pixel;
142
143 if (SDL_MUSTLOCK(gScreen))
144 if (SDL_LockSurface(gScreen) < 0)
145 return;
146
147 for(i=0; i < (Uint32)gScreen->w; i++) {
148 for(j=0; j < (Uint32)gScreen->h; j++) {
149 pixel = ((Uint32 *)gScreen->pixels)[j * pitch + i];
150
151 pixel = ((pixel & 0xff) +
152 ((pixel / 256) & 0xff) +
153 ((pixel / 65536) & 0xff)) / 3;
154 if(pixel > 255) {
155 pixel = 255;
156 }
157
158 pixel = pixel + pixel * 256 + pixel * 65536;
159
160 ((Uint32 *)gScreen->pixels)[j * pitch + i] = pixel;
161 }
162 }
163
164 if (SDL_MUSTLOCK(gScreen))
165 SDL_UnlockSurface(gScreen);
166 }
167
BS_SetVideoMode(Uint32 width,Uint32 height,Uint32 depth,Uint32 flags)168 SDL_Surface* BS_SetVideoMode(Uint32 width, Uint32 height, Uint32 depth, Uint32 flags) {
169 /* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order,
170 as expected by OpenGL for textures */
171 Uint32 rmask, gmask, bmask, amask;
172 SDL_Surface *temp;
173
174 /* SDL interprets each pixel as a 32-bit number, so our masks must depend
175 on the endianness (byte order) of the machine */
176 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
177 rmask = 0xff000000;
178 gmask = 0x00ff0000;
179 bmask = 0x0000ff00;
180 amask = 0x000000ff;
181 #else
182 rmask = 0x000000ff;
183 gmask = 0x0000ff00;
184 bmask = 0x00ff0000;
185 amask = 0xff000000;
186 #endif
187
188
189 if(!realRes_enabled) {
190 gScreen = SDL_SetVideoMode(width, height, depth, flags);
191 } else {
192 if(realRes_gScreen && gScreen != realRes_gScreen) {
193 SDL_FreeSurface(gScreen);
194 }
195 realRes_gScreen = SDL_SetVideoMode(realRes_X, realRes_Y, depth, flags);
196 temp = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, depth, rmask, gmask, bmask, amask);
197 gScreen = SDL_DisplayFormat(temp);
198 SDL_FreeSurface(temp);
199 }
200
201 if(enableColor3D) {
202 gScreen_Normal = gScreen;
203
204 if(gScreen_Left) {
205 SDL_FreeSurface(gScreen_Left);
206 }
207 temp = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
208 gScreen_Left = SDL_DisplayFormat(temp);
209 SDL_FreeSurface(temp);
210
211 if(gScreen_Right) {
212 SDL_FreeSurface(gScreen_Right);
213 }
214 temp = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
215 gScreen_Right = SDL_DisplayFormat(temp);
216 SDL_FreeSurface(temp);
217 }
218
219 return gScreen;
220
221
222 }
223
BS_OLPCScreenZoom(SDL_Surface * src,SDL_Surface * dst)224 void BS_OLPCScreenZoom(SDL_Surface *src, SDL_Surface *dst) {
225 if (SDL_MUSTLOCK(src))
226 if (SDL_LockSurface(src) < 0)
227 return;
228 if (SDL_MUSTLOCK(dst))
229 if (SDL_LockSurface(dst) < 0)
230 return;
231
232 Uint32 srcpitch = src->pitch / 4;
233 Uint32 dstpitch = dst->pitch / 4;
234
235 for(Uint32 y = 0; y < SCR_HEIGHT; y++) {
236 for(Uint32 x = 0; x < SCR_WIDTH; x++) {
237 ((Uint32 *)dst->pixels)[(y * 2) * dstpitch + x * 2] =
238 ((Uint32 *)dst->pixels)[((y * 2) + 1)* dstpitch + x * 2] =
239 ((Uint32 *)dst->pixels)[(y * 2) * dstpitch + x * 2 + 1] =
240 ((Uint32 *)dst->pixels)[((y * 2) + 1)* dstpitch + x * 2 + 1] =
241 ((Uint32 *)src->pixels)[y * srcpitch + x];
242 }
243 }
244
245
246 if (SDL_MUSTLOCK(src))
247 SDL_UnlockSurface(src);
248 if (SDL_MUSTLOCK(dst))
249 SDL_UnlockSurface(dst);
250
251 }
252
BS_Flip(SDL_Surface * myscreen)253 int BS_Flip(SDL_Surface* myscreen) {
254 SDL_Surface *tmpScreen = 0;
255 if(!enableColor3D && (!realRes_gScreen || myscreen != gScreen)) {
256 return SDL_Flip(myscreen);
257 } else {
258 if(enableColor3D) {
259 if(useColor3D) {
260 tmpScreen = gScreen;
261 gScreen = gScreen_Normal;
262 BS_ColorSurfacesToScreen();
263 } else {
264 // Make screen Greyscale - if we don't,
265 // the player may see some unwanted and very irritating
266 // 3D effects in videos, images und menu
267 BS_ColorToGreyscale();
268 }
269 }
270
271 if(realRes_enabled) {
272 #ifdef OLPCBUILD
273 BS_OLPCScreenZoom(gScreen, realRes_gScreen);
274 #else // NO OLPCBUILD
275 if(realRes_smoothieZoom) {
276 zoomSurfaceRGBA(gScreen, realRes_gScreen, 0, 0, 1);
277 } else {
278 zoomSurfaceRGBA(gScreen, realRes_gScreen, 0, 0, 0);
279 }
280 #endif
281 SDL_Flip(realRes_gScreen);
282 } else {
283 SDL_Flip(gScreen);
284 }
285 if(enableColor3D) {
286 if(useColor3D) {
287 gScreen = tmpScreen;
288 }
289 }
290
291 return 0;
292 //return SDL_Flip(realRes_gScreen);
293 }
294 }
295
296 //BS_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 32, SDL_SWSURFACE | SDL_FULLSCREEN);
297