20 #define XEP128_NEED_SDL_WMINFO
27 #ifdef CONFIG_USE_LODEPNG
33 #ifndef __EMSCRIPTEN__
34 #include "xemu/../rom/ep128/app_icon.c"
46 static SDL_Renderer *
sdl_ren = NULL;
47 static SDL_Texture *
sdl_tex = NULL, *sdl_osdtex = NULL;
50 static int win_xsize, win_ysize, resize_counter = 0, win_size_changed = 0;
51 static int screenshot_index = 0;
52 static Uint32 *osd_pixels = NULL;
53 static int osd_on = 0, osd_fade = 0;
54 static Uint32 osd_fg_colour, osd_bg_colour;
58 static void _osd_set_alpha (
int alpha )
62 SDL_SetTextureAlphaMod(sdl_osdtex, alpha);
85 void osd_set_colour (
int fg_r,
int fg_g,
int fg_b,
int fg_a,
int bg_r,
int bg_g,
int bg_b,
int bg_a )
97 for (row = 0; row < 16; row++) {
100 *(d++) = *s &
mask ? osd_fg_colour : osd_bg_colour;
122 char *p = strchr(s,
'\n');
123 int n = p ? (p++) - s : strlen(s);
149 _osd_set_alpha(0xFF);
161 }
if (state == SDL_TRUE)
162 OSD(
"Mouse grab\nPress ESC to leave.");
163 DEBUG(
"UI: GRAB: %d" NL, state);
164 SDL_SetRelativeMouseMode(state);
165 SDL_SetWindowGrab(
sdl_win, state);
169 #define SCREEN_RATIO ((double)SCREEN_WIDTH / (double)(SCREEN_HEIGHT * 2))
177 if (new_xsize == win_xsize && new_ysize == win_ysize)
179 DEBUG(
"UI: window geometry change from %d x %d to %d x %d" NL, win_xsize, win_ysize, new_xsize, new_ysize);
180 if (new_ysize == 0) new_ysize = 1;
181 ratio = (float)new_xsize / (
float)new_ysize;
182 if (new_xsize * new_ysize > win_xsize * win_ysize) {
197 win_xsize = new_xsize;
198 win_ysize = new_ysize;
200 win_size_changed = 1;
209 SDL_GetWindowSize(
sdl_win, &win_xsize, &win_ysize);
210 if (SDL_SetWindowFullscreen(
sdl_win, SDL_WINDOW_FULLSCREEN_DESKTOP)) {
211 ERROR_WINDOW(
"Cannot enter fullscreen: %s", SDL_GetError());
214 DEBUG(
"UI: entering full screen mode" NL);
219 SDL_SetWindowFullscreen(
sdl_win, 0);
220 SDL_SetWindowSize(
sdl_win, win_xsize, win_ysize);
222 DEBUG(
"UI: leaving full screen mode" NL);
229 int need = (osd_on && sdl_osdtex != NULL) || !
paused;
230 if (resize_counter == 10) {
231 if (win_size_changed) {
232 SDL_SetWindowSize(
sdl_win, win_xsize, win_ysize);
233 DEBUG(
"UI: correcting window size to %d x %d" NL, win_xsize, win_ysize);
234 win_size_changed = 0;
245 if (osd_on && sdl_osdtex != NULL)
246 SDL_RenderCopy(
sdl_ren, sdl_osdtex, NULL, NULL);
253 _osd_set_alpha(osd_fade);
256 DEBUG(
"OSD: turned off on fading out" NL);
268 char fn[PATH_MAX + 1], *p;
272 ERROR_WINDOW(
"Not enough memory for taking a screenshot :(");
276 strcpy(
fn, directory);
279 p = strchr(filename,
'*');
282 memcpy(
fn + a, filename, p - filename);
283 sprintf(
fn + a + (p - filename),
"%d", screenshot_index);
287 strcat(
fn, filename);
290 pix[d + 0] = pix[d + 0 +
SCREEN_WIDTH * 3] = (ep_pixels[a] >> 16) & 0xFF;
291 pix[d + 1] = pix[d + 1 +
SCREEN_WIDTH * 3] = (ep_pixels[a] >> 8) & 0xFF;
292 pix[d + 2] = pix[d + 2 +
SCREEN_WIDTH * 3] = ep_pixels[a] & 0xFF;
300 OSD(
"Screenshot:\n%s",
fn + strlen(directory));
308 #ifndef __EMSCRIPTEN__
309 static void set_app_icon ( SDL_Window *win,
const void *app_icon )
311 SDL_Surface *surf = SDL_CreateRGBSurfaceFrom((
void*)app_icon,96,96,32,96*4,0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
313 DEBUG(
"Cannot create surface for window icon: %s" NL, SDL_GetError());
315 SDL_SetWindowIcon(win, surf);
316 SDL_FreeSurface(surf);
322 static SDL_bool XEP128_SDL_SetHint (
const char *sdl_hint_name,
const char *cfg_sub_key,
const char *defval )
325 const char *p = config_getopt_str(
"sdl");
326 if (!strchr(p,
'=')) {
328 return SDL_SetHint(sdl_hint_name, defval);
333 char *q = strchr(p,
':');
335 if (!strncasecmp(p, cfg_sub_key, strlen(cfg_sub_key)) && p[strlen(cfg_sub_key)] ==
'=') {
336 p += strlen(cfg_sub_key) + 1;
338 memcpy(res, p, q - p - 1);
339 res[q - p - 1] =
'\0';
342 DEBUGPRINT(
"SDL: setting hint \"%s\" [cfg: \"%s\"] to \"%s\"" NL, sdl_hint_name, cfg_sub_key, res);
343 return SDL_SetHint(sdl_hint_name, res);
347 DEBUGPRINT(
"SDL: cannot found hint \"%s\" [cfg: \"%s\"] in sdl opt" NL, sdl_hint_name, cfg_sub_key);
349 DEBUGPRINT(
"SDL: ... so setting the Xep128 internal specified default: \"%s\"" NL, defval);
350 return SDL_SetHint(sdl_hint_name, defval);
361 XEP128_SDL_SetHint(SDL_HINT_RENDER_DRIVER,
"driver", NULL);
365 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
366 win_xsize, win_ysize,
367 SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
370 ERROR_WINDOW(
"Cannot open SDL window: %s", SDL_GetError());
374 #ifndef __EMSCRIPTEN__
378 DEBUGPRINT(
"UI: warning WMInfo call falied: %s", SDL_GetError());
383 #ifndef __EMSCRIPTEN__
384 set_app_icon(
sdl_win, _icon_pixels);
387 #ifdef __EMSCRIPTEN__
395 ERROR_WINDOW(
"Cannot create SDL renderer: %s", SDL_GetError());
399 XEP128_SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_PING,
"wmping",
"0");
400 XEP128_SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY,
"quality",
"1");
401 XEP128_SDL_SetHint(SDL_HINT_RENDER_VSYNC,
"vsync",
"0");
403 XEP128_SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4,
"noaltf4",
"1");
405 XEP128_SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS,
"focuslossmin",
"1");
406 XEP128_SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER,
"screensaver",
"1");
409 ERROR_WINDOW(
"Cannot create SDL texture: %s", SDL_GetError());
413 if (osd_pixels != NULL) {
415 if (sdl_osdtex == NULL) {
416 ERROR_WINDOW(
"Cannot create texture for OSD rendering, OSD won't work: %s", SDL_GetError());
421 if (SDL_SetTextureBlendMode(sdl_osdtex, SDL_BLENDMODE_BLEND))
422 ERROR_WINDOW(
"Warning, SDL BLEND mode cannot be used for OSD, there can be fade out problems.\n%s", SDL_GetError());
425 ERROR_WINDOW(
"Not enough memory for OSD pixel buffer. OSD won't work");
427 DEBUG(
"SDL: everything seems to be OK ..." NL);
437 SDL_FlushEvent(SDL_KEYDOWN);
438 SDL_FlushEvent(SDL_KEYUP);
439 SDL_FlushEvent(SDL_MOUSEMOTION);
440 SDL_FlushEvent(SDL_MOUSEWHEEL);
441 SDL_FlushEvent(SDL_MOUSEBUTTONDOWN);
442 SDL_FlushEvent(SDL_MOUSEBUTTONUP);
453 #ifdef __EMSCRIPTEN__
454 if (1 || sdlflag == SDL_MESSAGEBOX_ERROR) {
456 window.alert(Pointer_stringify($0));
471 char items_buf[512], *
items = items_buf;
473 SDL_MessageBoxButtonData buttons[16];
474 SDL_MessageBoxData messageboxdata = {
475 SDL_MESSAGEBOX_INFORMATION,
483 strcpy(items_buf, items_in);
485 char *p = strchr(
items,
'|');
488 #ifdef __EMSCRIPTEN__
489 DEBUGPRINT(
"Emscripten: faking chooser box answer %d for \"%s\"" NL, messageboxdata.numbuttons, msg);
490 return messageboxdata.numbuttons;
492 buttons[messageboxdata.numbuttons].flags = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
496 buttons[messageboxdata.numbuttons].flags = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
500 buttons[messageboxdata.numbuttons].flags = 0;
503 buttons[messageboxdata.numbuttons].text =
items;
504 buttons[messageboxdata.numbuttons].buttonid = messageboxdata.numbuttons;
505 messageboxdata.numbuttons++;
506 if (p == NULL)
break;
513 SDL_ShowMessageBox(&messageboxdata, &buttonid);