1 /*
2 * OpenBOR - http://www.chronocrash.com
3 * -----------------------------------------------------------------------
4 * All rights reserved, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2014 OpenBOR Team
7 */
8 #if ANDROID
9
10 // CRxTRDude - changed the directory for neatness.
11 #include "android/app/jni/openbor/video.c"
12
13 #else
14
15 #include "sdlport.h"
16 #include <math.h>
17 #include "types.h"
18 #include "video.h"
19 #include "vga.h"
20 #include "screen.h"
21 #include "opengl.h"
22 #include "savedata.h"
23 #include "gfxtypes.h"
24 #include "gfx.h"
25 #include "pngdec.h"
26 #include "videocommon.h"
27 #include "../resources/OpenBOR_Icon_32x32_png.h"
28
29 SDL_Window *window = NULL;
30 static SDL_Renderer *renderer = NULL;
31 static SDL_Texture *texture = NULL;
32 s_videomodes stored_videomodes;
33 yuv_video_mode stored_yuv_mode;
34 int yuv_mode = 0;
35 char windowTitle[MAX_LABEL_LEN] = {"OpenBOR"};
36 int stretch = 0;
37 int opengl = 0; // OpenGL backend currently in use?
38 int nativeWidth, nativeHeight; // monitor resolution used in fullscreen mode
39 int brightness = 0;
40
initSDL()41 void initSDL()
42 {
43 SDL_DisplayMode video_info;
44 int init_flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC;
45
46 /*#if EE_CURRENT_PLATFORM == EE_PLATFORM_WINDOWS
47 SDL_setenv("SDL_AUDIODRIVER", "directsound", true);
48 #endif*/
49
50 if(SDL_Init(init_flags) < 0)
51 {
52 printf("SDL Failed to Init!!!! (%s)\n", SDL_GetError());
53 borExit(0);
54 }
55 SDL_ShowCursor(SDL_DISABLE);
56 //atexit(SDL_Quit); //White Dragon: use SDL_Quit() into sdlport.c it's best practice!
57
58 #ifdef LOADGL
59 if(SDL_GL_LoadLibrary(NULL) < 0)
60 {
61 printf("Warning: couldn't load OpenGL library (%s)\n", SDL_GetError());
62 }
63 #endif
64
65 SDL_GetCurrentDisplayMode(0, &video_info);
66 nativeWidth = video_info.w;
67 nativeHeight = video_info.h;
68 printf("debug:nativeWidth, nativeHeight, bpp, Hz %d, %d, %d, %d\n", nativeWidth, nativeHeight, SDL_BITSPERPIXEL(video_info.format), video_info.refresh_rate);
69 }
70
video_set_window_title(const char * title)71 void video_set_window_title(const char* title)
72 {
73 if(window) SDL_SetWindowTitle(window, title);
74 strncpy(windowTitle, title, sizeof(windowTitle)-1);
75 }
76
77 static unsigned pixelformats[4] = {SDL_PIXELFORMAT_INDEX8, SDL_PIXELFORMAT_BGR565, SDL_PIXELFORMAT_BGR888, SDL_PIXELFORMAT_ABGR8888};
78
SetVideoMode(int w,int h,int bpp,bool gl)79 int SetVideoMode(int w, int h, int bpp, bool gl)
80 {
81 int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS;
82 static bool last_gl = false;
83 static int last_x = SDL_WINDOWPOS_UNDEFINED;
84 static int last_y = SDL_WINDOWPOS_UNDEFINED;
85
86 if(gl) flags |= SDL_WINDOW_OPENGL;
87 if(savedata.fullscreen) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
88
89 if(!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP))
90 SDL_GetWindowPosition(window, &last_x, &last_y);
91
92 if(window && gl != last_gl)
93 {
94 SDL_DestroyWindow(window);
95 window = NULL;
96 }
97 last_gl = gl;
98
99 if(renderer) SDL_DestroyRenderer(renderer);
100 if(texture) SDL_DestroyTexture(texture);
101 renderer = NULL;
102 texture = NULL;
103
104 if(window)
105 {
106 if(savedata.fullscreen)
107 {
108 SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
109 }
110 else
111 {
112 #ifndef WIN // hiding and showing the window is problematic on Windows
113 if(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP)
114 SDL_HideWindow(window);
115 #endif
116 SDL_SetWindowFullscreen(window, 0);
117 SDL_SetWindowSize(window, w, h);
118 SDL_SetWindowPosition(window, last_x, last_y);
119 SDL_ShowWindow(window);
120 }
121 }
122 else
123 {
124 window = SDL_CreateWindow(windowTitle, last_x, last_y, w, h, flags);
125 if(!window)
126 {
127 printf("Error: failed to create window: %s\n", SDL_GetError());
128 return 0;
129 }
130 SDL_Surface* icon = (SDL_Surface*)pngToSurface((void*)openbor_icon_32x32_png.data);
131 SDL_SetWindowIcon(window, icon);
132 SDL_FreeSurface(icon);
133 if(!savedata.fullscreen) SDL_GetWindowPosition(window, &last_x, &last_y);
134 }
135
136 if(!gl)
137 {
138 renderer = SDL_CreateRenderer(window, -1, savedata.vsync ? SDL_RENDERER_PRESENTVSYNC : 0);
139 if(!renderer)
140 {
141 printf("Error: failed to create renderer: %s\n", SDL_GetError());
142 return 0;
143 }
144 }
145
146 return 1;
147 }
148
video_set_mode(s_videomodes videomodes)149 int video_set_mode(s_videomodes videomodes)
150 {
151 stored_videomodes = videomodes;
152 yuv_mode = 0;
153
154 if(videomodes.hRes==0 && videomodes.vRes==0)
155 {
156 Term_Gfx();
157 return 0;
158 }
159
160 videomodes = setupPreBlitProcessing(videomodes);
161
162 // 8-bit color should be transparently converted to 32-bit
163 assert(videomodes.pixel == 2 || videomodes.pixel == 4);
164
165 // try OpenGL initialization first
166 if(savedata.usegl && video_gl_set_mode(videomodes)) return 1;
167 else opengl = 0;
168
169 if(!SetVideoMode(videomodes.hRes * videomodes.hScale,
170 videomodes.vRes * videomodes.vScale,
171 videomodes.pixel * 8, false))
172 {
173 return 0;
174 }
175
176 if(savedata.hwfilter ||
177 (videomodes.hScale == 1 && videomodes.vScale == 1 && !savedata.fullscreen))
178 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
179 else
180 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
181
182 texture = SDL_CreateTexture(renderer,
183 pixelformats[videomodes.pixel-1],
184 SDL_TEXTUREACCESS_STREAMING,
185 videomodes.hRes, videomodes.vRes);
186
187 SDL_ShowCursor(SDL_DISABLE);
188 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
189 video_stretch(savedata.stretch);
190
191 return 1;
192 }
193
video_fullscreen_flip()194 void video_fullscreen_flip()
195 {
196 int restore_yuv = yuv_mode;
197 savedata.fullscreen ^= 1;
198 if(window) video_set_mode(stored_videomodes);
199 if(restore_yuv) video_setup_yuv_overlay(&stored_yuv_mode);
200 }
201
blit()202 void blit()
203 {
204 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
205 SDL_RenderClear(renderer);
206 SDL_RenderCopy(renderer, texture, NULL, NULL);
207
208 if (brightness > 0)
209 SDL_SetRenderDrawColor(renderer, 255, 255, 255, brightness-1);
210 else if (brightness < 0)
211 SDL_SetRenderDrawColor(renderer, 0, 0, 0, (-brightness)-1);
212 SDL_RenderFillRect(renderer, NULL);
213
214 SDL_RenderPresent(renderer);
215 }
216
video_copy_screen(s_screen * src)217 int video_copy_screen(s_screen* src)
218 {
219 // do any needed scaling and color conversion
220 s_videosurface *surface = getVideoSurface(src);
221
222 if(opengl) return video_gl_copy_screen(surface);
223
224 SDL_UpdateTexture(texture, NULL, surface->data, surface->pitch);
225 blit();
226
227 return 1;
228 }
229
video_clearscreen()230 void video_clearscreen()
231 {
232 if(opengl) { video_gl_clearscreen(); return; }
233
234 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
235 SDL_RenderClear(renderer);
236 SDL_RenderPresent(renderer);
237 }
238
video_stretch(int enable)239 void video_stretch(int enable)
240 {
241 stretch = enable;
242 if(window && !opengl)
243 {
244 if(stretch)
245 SDL_RenderSetLogicalSize(renderer, 0, 0);
246 else
247 SDL_RenderSetLogicalSize(renderer, stored_videomodes.hRes, stored_videomodes.vRes);
248 }
249 }
250
video_set_color_correction(int gm,int br)251 void video_set_color_correction(int gm, int br)
252 {
253 brightness = br;
254 if(opengl) video_gl_set_color_correction(gm, br);
255 }
256
video_setup_yuv_overlay(const yuv_video_mode * mode)257 int video_setup_yuv_overlay(const yuv_video_mode *mode)
258 {
259 stored_yuv_mode = *mode;
260 yuv_mode = 1;
261 if(opengl) return video_gl_setup_yuv_overlay(mode);
262
263 SDL_DestroyTexture(texture);
264 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
265 texture = SDL_CreateTexture(renderer,
266 SDL_PIXELFORMAT_YV12,
267 SDL_TEXTUREACCESS_STREAMING,
268 mode->width, mode->height);
269 if(!stretch)
270 SDL_RenderSetLogicalSize(renderer, mode->display_width, mode->display_height);
271 return texture ? 1 : 0;
272 }
273
video_prepare_yuv_frame(yuv_frame * src)274 int video_prepare_yuv_frame(yuv_frame *src)
275 {
276 if(opengl) return video_gl_prepare_yuv_frame(src);
277
278 SDL_UpdateYUVTexture(texture, NULL, src->lum, stored_yuv_mode.width,
279 src->cr, stored_yuv_mode.width/2, src->cb, stored_yuv_mode.width/2);
280 return 1;
281 }
282
video_display_yuv_frame(void)283 int video_display_yuv_frame(void)
284 {
285 if(opengl) return video_gl_display_yuv_frame();
286
287 blit();
288 return 1;
289 }
290
vga_vwait(void)291 void vga_vwait(void)
292 {
293 static int prevtick = 0;
294 int now = SDL_GetTicks();
295 int wait = 1000/60 - (now - prevtick);
296 if (wait>0)
297 {
298 SDL_Delay(wait);
299 }
300 else SDL_Delay(1);
301 prevtick = now;
302 }
303
304 #endif
305