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