static void GLimp_DetectAvailableModes(void) { int i, j; char buf[MAX_STRING_CHARS] = { 0 }; SDL_Rect modes[128]; int numModes = 0; int display = 0; SDL_DisplayMode windowMode; if (!main_window) { if (!SDL_GetNumVideoDisplays()) { Ren_Fatal("There is no available display to open a game screen - %s", SDL_GetError()); return; } // Use the zero display index display = 0; } else { // Detect the used display display = SDL_GetWindowDisplayIndex(main_window); } // was SDL_GetWindowDisplayMode if (SDL_GetDesktopDisplayMode(display, &windowMode) < 0) { Ren_Warning("Couldn't get desktop display mode, no resolutions detected - %s\n", SDL_GetError()); return; } for (i = 0; i < SDL_GetNumDisplayModes(display); i++) { SDL_DisplayMode mode; if (SDL_GetDisplayMode(display, i, &mode) < 0) { continue; } if (!mode.w || !mode.h) { Ren_Print("Display supports any resolution\n"); return; } if (windowMode.format != mode.format) { continue; } // SDL can give the same resolution with different refresh rates. // Only list resolution once. for (j = 0; j < numModes; j++) { if (mode.w == modes[j].w && mode.h == modes[j].h) { break; } } if (j != numModes) { continue; } modes[numModes].w = mode.w; modes[numModes].h = mode.h; numModes++; } if (numModes > 1) { qsort(modes, numModes, sizeof(SDL_Rect), GLimp_CompareModes); } for (i = 0; i < numModes; i++) { const char *newModeString = va("%ux%u ", modes[i].w, modes[i].h); if (strlen(newModeString) < (int)sizeof(buf) - strlen(buf)) { Q_strcat(buf, sizeof(buf), newModeString); } else { Ren_Warning("Skipping mode %ux%u, buffer too small\n", modes[i].w, modes[i].h); } } if (*buf) { buf[strlen(buf) - 1] = 0; Ren_Print("Available modes [%i]: '%s'\n", numModes, buf); ri.Cvar_Set("r_availableModes", buf); } }
static void *sdl2_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { int i; unsigned flags; settings_t *settings = config_get_ptr(); #ifdef HAVE_X11 XInitThreads(); #endif if (SDL_WasInit(0) == 0) { if (SDL_Init(SDL_INIT_VIDEO) < 0) return NULL; } else if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) return NULL; sdl2_video_t *vid = (sdl2_video_t*)calloc(1, sizeof(*vid)); if (!vid) return NULL; RARCH_LOG("[SDL]: Available renderers (change with $SDL_RENDER_DRIVER):\n"); for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { SDL_RendererInfo renderer; if (SDL_GetRenderDriverInfo(i, &renderer) == 0) RARCH_LOG("\t%s\n", renderer.name); } RARCH_LOG("[SDL]: Available displays:\n"); for(i = 0; i < SDL_GetNumVideoDisplays(); ++i) { SDL_DisplayMode mode; if (SDL_GetCurrentDisplayMode(i, &mode) < 0) RARCH_LOG("\tDisplay #%i mode: unknown.\n", i); else RARCH_LOG("\tDisplay #%i mode: %ix%i@%ihz.\n", i, mode.w, mode.h, mode.refresh_rate); } // void *sdl_input = NULL; if (!video->fullscreen) RARCH_LOG("[SDL]: Creating window @ %ux%u\n", video->width, video->height); if (video->fullscreen) flags = settings->video.windowed_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN; else flags = SDL_WINDOW_RESIZABLE; vid->window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, video->width, video->height, flags); if (!vid->window) { RARCH_ERR("[SDL]: Failed to init SDL window: %s\n", SDL_GetError()); goto error; } vid->video = *video; vid->video.smooth = settings->video.smooth; vid->should_resize = true; sdl_tex_zero(&vid->frame); sdl_tex_zero(&vid->menu); if (video->fullscreen) SDL_ShowCursor(SDL_DISABLE); sdl2_init_renderer(vid); sdl2_init_font(vid, settings->video.font_path, settings->video.font_size); sdl2_gfx_set_handles(vid); *input = NULL; *input_data = NULL; return vid; error: sdl2_gfx_free(vid); return NULL; }
static void graphics_ReadVideoModes(void) { // free old video mode data if (videomodesx) { free(videomodesx); videomodesx = 0; } if (videomodesy) { free(videomodesy); videomodesy = 0; } // -> read video modes with SDL per default! (even if using 3d/ogre) // allocate space for video modes int d = SDL_GetNumVideoDisplays(); if (d < 1) { return; } int c = SDL_GetNumDisplayModes(0); int i = 0; videomodesx = (int*)malloc((c+1)*sizeof(int)); videomodesy = (int*)malloc((c+1)*sizeof(int)); if (!videomodesx || !videomodesy) { if (videomodesx) { free(videomodesx); } if (videomodesy) { free(videomodesy); } return; } memset(videomodesx, 0, (c+1) * sizeof(int)); memset(videomodesy, 0, (c+1) * sizeof(int)); // read video modes int lastusedindex = -1; while (i < c) { SDL_DisplayMode m; if (SDL_GetDisplayMode(0, i, &m) == 0) { if (m.w > 0 && m.h > 0) { // first, check for duplicates int isduplicate = 0; int j = 0; while (j <= lastusedindex && videomodesx[j] > 0 && videomodesy[j] > 0) { if (videomodesx[j] == m.w && videomodesy[j] == m.h) { isduplicate = 1; break; } j++; } if (isduplicate) { i++; continue; } // add mode lastusedindex++; videomodesx[lastusedindex] = m.w; videomodesy[lastusedindex] = m.h; } } i++; } }
TCOD_sys_save_bitmap((void *)screenshot,filename); SDL_FreeSurface(screenshot); #endif } } /* get desktop resolution */ static void get_current_resolution(int *w, int *h) { int displayidx; SDL_Rect rect = { 0, 0, 0, 0 }; if (window) { TCOD_IFNOT(window) return; displayidx = SDL_GetWindowDisplayIndex(window); TCOD_IFNOT(displayidx >= 0) return; } else { /* No window if no console, but user can want to know res before opening one. */ TCOD_IFNOT(SDL_GetNumVideoDisplays() > 0) return; displayidx = 0; } TCOD_IFNOT(SDL_GetDisplayBounds(displayidx, &rect) == 0) return; *w=rect.w; *h=rect.h; } static void set_mouse_position(int x, int y) { SDL_WarpMouseInWindow(window, (Uint16)x,(Uint16)y); } /* android compatible file access functions */ static bool file_read(const char *filename, unsigned char **buf, size_t *size) { uint32 filesize; /* get file size */
/* =============== GLimp_StartDriverAndSetMode =============== */ static qboolean GLimp_StartDriverAndSetMode( int mode, qboolean fullscreen, qboolean noborder ) { rserr_t err; int numDisplays; if ( !SDL_WasInit( SDL_INIT_VIDEO ) ) { const char *driverName; SDL_version v; SDL_GetVersion( &v ); ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO )... " ); ri.Printf( PRINT_ALL, "Using SDL Version %u.%u.%u\n", v.major, v.minor, v.patch ); if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) == -1 ) { ri.Printf( PRINT_ALL, "SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) FAILED (%s)\n", SDL_GetError() ); return qfalse; } driverName = SDL_GetCurrentVideoDriver(); if ( !driverName ) { ri.Error( ERR_FATAL, "No video driver initialized\n" ); } ri.Printf( PRINT_ALL, "SDL using driver \"%s\"\n", driverName ); ri.Cvar_Set( "r_sdlDriver", driverName ); } numDisplays = SDL_GetNumVideoDisplays(); if ( numDisplays <= 0 ) { ri.Error( ERR_FATAL, "SDL_GetNumVideoDisplays FAILED (%s)\n", SDL_GetError() ); } AssertCvarRange( r_displayIndex, 0, numDisplays - 1, qtrue ); if ( fullscreen && ri.Cvar_VariableIntegerValue( "in_nograb" ) ) { ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n" ); ri.Cvar_Set( "r_fullscreen", "0" ); r_fullscreen->modified = qfalse; fullscreen = qfalse; } err = (rserr_t) GLimp_SetMode( mode, fullscreen, noborder ); switch ( err ) { case RSERR_INVALID_FULLSCREEN: ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" ); return qfalse; case RSERR_INVALID_MODE: ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode ); return qfalse; case RSERR_OLD_GL: ri.Printf( PRINT_ALL, "...WARNING: OpenGL too old\n" ); return qfalse; default: break; } return qtrue; }
SDL_bool CommonInit(CommonState * state) { int i, j, m, n; SDL_DisplayMode fullscreen_mode; if (state->flags & SDL_INIT_VIDEO) { if (state->verbose & VERBOSE_VIDEO) { n = SDL_GetNumVideoDrivers(); if (n == 0) { fprintf(stderr, "No built-in video drivers\n"); } else { fprintf(stderr, "Built-in video drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetVideoDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_VideoInit(state->videodriver) < 0) { fprintf(stderr, "Couldn't initialize video driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Video driver: %s\n", SDL_GetCurrentVideoDriver()); } /* Upload GL settings */ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size); SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples); if (state->gl_accelerated >= 0) { SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, state->gl_accelerated); } SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing); if (state->gl_major_version) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version); } if (state->verbose & VERBOSE_MODES) { SDL_DisplayMode mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; n = SDL_GetNumVideoDisplays(); fprintf(stderr, "Number of displays: %d\n", n); for (i = 0; i < n; ++i) { fprintf(stderr, "Display %d:\n", i); SDL_GetDesktopDisplayMode(i, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n", mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } /* Print available fullscreen video modes */ m = SDL_GetNumDisplayModes(i); if (m == 0) { fprintf(stderr, "No available fullscreen video modes\n"); } else { fprintf(stderr, " Fullscreen video modes:\n"); for (j = 0; j < m; ++j) { SDL_GetDisplayMode(i, j, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n", j, mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } } } } } if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); if (n == 0) { fprintf(stderr, "No built-in render drivers\n"); } else { fprintf(stderr, "Built-in render drivers:\n"); for (i = 0; i < n; ++i) { SDL_GetRenderDriverInfo(i, &info); PrintRenderer(&info); } } } SDL_zero(fullscreen_mode); switch (state->depth) { case 8: fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; break; case 15: fullscreen_mode.format = SDL_PIXELFORMAT_RGB555; break; case 16: fullscreen_mode.format = SDL_PIXELFORMAT_RGB565; break; case 24: fullscreen_mode.format = SDL_PIXELFORMAT_RGB24; break; default: fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; break; } fullscreen_mode.refresh_rate = state->refresh_rate; state->windows = (SDL_Window **) SDL_malloc(state->num_windows * sizeof(*state->windows)); state->renderers = (SDL_Renderer **) SDL_malloc(state->num_windows * sizeof(*state->renderers)); if (!state->windows || !state->renderers) { fprintf(stderr, "Out of memory!\n"); return SDL_FALSE; } for (i = 0; i < state->num_windows; ++i) { char title[1024]; if (state->num_windows > 1) { SDL_snprintf(title, SDL_arraysize(title), "%s %d", state->window_title, i + 1); } else { SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); } state->windows[i] = SDL_CreateWindow(title, state->window_x, state->window_y, state->window_w, state->window_h, state->window_flags); if (!state->windows[i]) { fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); return SDL_FALSE; } SDL_GetWindowSize(state->windows[i], &state->window_w, &state->window_h); if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { fprintf(stderr, "Can't set up fullscreen display mode: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->window_icon) { SDL_Surface *icon = LoadIcon(state->window_icon); if (icon) { SDL_SetWindowIcon(state->windows[i], icon); SDL_FreeSurface(icon); } } SDL_ShowWindow(state->windows[i]); state->renderers[i] = NULL; if (!state->skip_renderer && (state->renderdriver || !(state->window_flags & SDL_WINDOW_OPENGL))) { m = -1; if (state->renderdriver) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); for (j = 0; j < n; ++j) { SDL_GetRenderDriverInfo(j, &info); if (SDL_strcasecmp(info.name, state->renderdriver) == 0) { m = j; break; } } if (m == n) { fprintf(stderr, "Couldn't find render driver named %s", state->renderdriver); return SDL_FALSE; } } state->renderers[i] = SDL_CreateRenderer(state->windows[i], m, state->render_flags); if (!state->renderers[i]) { fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; fprintf(stderr, "Current renderer:\n"); SDL_GetRendererInfo(state->renderers[i], &info); PrintRenderer(&info); } } } } if (state->flags & SDL_INIT_AUDIO) { if (state->verbose & VERBOSE_AUDIO) { n = SDL_GetNumAudioDrivers(); if (n == 0) { fprintf(stderr, "No built-in audio drivers\n"); } else { fprintf(stderr, "Built-in audio drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetAudioDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_AudioInit(state->audiodriver) < 0) { fprintf(stderr, "Couldn't initialize audio driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Audio driver: %s\n", SDL_GetCurrentAudioDriver()); } if (SDL_OpenAudio(&state->audiospec, NULL) < 0) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return SDL_FALSE; } } return SDL_TRUE; }
int main(int argc, char *argv[]) { const SDL_VideoInfo *info; int i, d, n; const char *driver; SDL_DisplayMode mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; int nmodes; /* Print available video drivers */ n = SDL_GetNumVideoDrivers(); if (n == 0) { printf("No built-in video drivers\n"); } else { printf("Built-in video drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { printf(","); } printf(" %s", SDL_GetVideoDriver(i)); } printf("\n"); } if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } driver = SDL_GetCurrentVideoDriver(); if (driver) { printf("Video driver: %s\n", driver); } printf("Number of displays: %d\n", SDL_GetNumVideoDisplays()); for (d = 0; d < SDL_GetNumVideoDisplays(); ++d) { SDL_Rect bounds; SDL_GetDisplayBounds(d, &bounds); printf("Display %d: %dx%d at %d,%d\n", d, bounds.w, bounds.h, bounds.x, bounds.y); SDL_GetDesktopDisplayMode(d, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); printf(" Current mode: %dx%d@%dHz, %d bits-per-pixel\n", mode.w, mode.h, mode.refresh_rate, bpp); if (Rmask || Gmask || Bmask) { printf(" Red Mask = 0x%.8x\n", Rmask); printf(" Green Mask = 0x%.8x\n", Gmask); printf(" Blue Mask = 0x%.8x\n", Bmask); if (Amask) printf(" Alpha Mask = 0x%.8x\n", Amask); } /* Print available fullscreen video modes */ nmodes = SDL_GetNumDisplayModes(d); if (nmodes == 0) { printf("No available fullscreen video modes\n"); } else { printf(" Fullscreen video modes:\n"); for (i = 0; i < nmodes; ++i) { SDL_GetDisplayMode(d, i, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); printf(" Mode %d: %dx%d@%dHz, %d bits-per-pixel\n", i, mode.w, mode.h, mode.refresh_rate, bpp); if (Rmask || Gmask || Bmask) { printf(" Red Mask = 0x%.8x\n", Rmask); printf(" Green Mask = 0x%.8x\n", Gmask); printf(" Blue Mask = 0x%.8x\n", Bmask); if (Amask) printf(" Alpha Mask = 0x%.8x\n", Amask); } } } } info = SDL_GetVideoInfo(); if (info->wm_available) { printf("A window manager is available\n"); } if (info->hw_available) { printf("Hardware surfaces are available (%dK video memory)\n", info->video_mem); } if (info->blit_hw) { printf("Copy blits between hardware surfaces are accelerated\n"); } if (info->blit_hw_CC) { printf("Colorkey blits between hardware surfaces are accelerated\n"); } if (info->blit_hw_A) { printf("Alpha blits between hardware surfaces are accelerated\n"); } if (info->blit_sw) { printf ("Copy blits from software surfaces to hardware surfaces are accelerated\n"); } if (info->blit_sw_CC) { printf ("Colorkey blits from software surfaces to hardware surfaces are accelerated\n"); } if (info->blit_sw_A) { printf ("Alpha blits from software surfaces to hardware surfaces are accelerated\n"); } if (info->blit_fill) { printf("Color fills on hardware surfaces are accelerated\n"); } printf("Current resolution: %dx%d\n", info->current_w, info->current_h); #if 0 if (argv[1] && (strcmp(argv[1], "-benchmark") == 0)) { RunVideoTests(); } #endif SDL_Quit(); return (0); }
GHOST_TUns8 GHOST_SystemSDL::getNumDisplays() const { return SDL_GetNumVideoDisplays(); }
/* =================== GLimp_Init =================== */ bool GLimp_Init( glimpParms_t parms ) { common->Printf( "Initializing OpenGL subsystem\n" ); GLimp_PreInit(); // DG: make sure SDL is initialized // DG: make window resizable Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; // DG end if( parms.fullScreen ) flags |= SDL_WINDOW_FULLSCREEN; int colorbits = 24; int depthbits = 24; int stencilbits = 8; for( int i = 0; i < 16; i++ ) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if( ( i % 4 ) == 0 && i ) { // one pass, reduce switch( i / 4 ) { case 2 : if( colorbits == 24 ) colorbits = 16; break; case 1 : if( depthbits == 24 ) depthbits = 16; else if( depthbits == 16 ) depthbits = 8; case 3 : if( stencilbits == 24 ) stencilbits = 16; else if( stencilbits == 16 ) stencilbits = 8; } } int tcolorbits = colorbits; int tdepthbits = depthbits; int tstencilbits = stencilbits; if( ( i % 4 ) == 3 ) { // reduce colorbits if( tcolorbits == 24 ) tcolorbits = 16; } if( ( i % 4 ) == 2 ) { // reduce depthbits if( tdepthbits == 24 ) tdepthbits = 16; else if( tdepthbits == 16 ) tdepthbits = 8; } if( ( i % 4 ) == 1 ) { // reduce stencilbits if( tstencilbits == 24 ) tstencilbits = 16; else if( tstencilbits == 16 ) tstencilbits = 8; else tstencilbits = 0; } int channelcolorbits = 4; if( tcolorbits == 24 ) channelcolorbits = 8; SDL_GL_SetAttribute( SDL_GL_RED_SIZE, channelcolorbits ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, channelcolorbits ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, channelcolorbits ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits ); SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits ); if( r_waylandcompat.GetBool() ) SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 0 ); else SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, channelcolorbits ); SDL_GL_SetAttribute( SDL_GL_STEREO, parms.stereo ? 1 : 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, parms.multiSamples ? 1 : 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, parms.multiSamples ); #if SDL_VERSION_ATLEAST(2, 0, 0) // RB begin if( r_useOpenGL32.GetInteger() > 0 ) { glConfig.driverType = GLDRV_OPENGL32_COMPATIBILITY_PROFILE; SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 ); if( r_debugContext.GetBool() ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); } } if( r_useOpenGL32.GetInteger() > 1 ) { glConfig.driverType = GLDRV_OPENGL32_CORE_PROFILE; SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); } // RB end // DG: set display num for fullscreen int windowPos = SDL_WINDOWPOS_UNDEFINED; if( parms.fullScreen > 0 ) { if( parms.fullScreen > SDL_GetNumVideoDisplays() ) { common->Warning( "Couldn't set display to num %i because we only have %i displays", parms.fullScreen, SDL_GetNumVideoDisplays() ); } else { // -1 because SDL starts counting displays at 0, while parms.fullScreen starts at 1 windowPos = SDL_WINDOWPOS_UNDEFINED_DISPLAY( ( parms.fullScreen - 1 ) ); } } // TODO: if parms.fullScreen == -1 there should be a borderless window spanning multiple displays /* * NOTE that this implicitly handles parms.fullScreen == -2 (from r_fullscreen -2) meaning * "do fullscreen, but I don't care on what monitor", at least on my box it's the monitor with * the mouse cursor. */ window = SDL_CreateWindow( GAME_NAME, windowPos, windowPos, parms.width, parms.height, flags ); // DG end context = SDL_GL_CreateContext( window ); if( !window ) { common->DPrintf( "Couldn't set GL mode %d/%d/%d: %s", channelcolorbits, tdepthbits, tstencilbits, SDL_GetError() ); continue; } if( SDL_GL_SetSwapInterval( r_swapInterval.GetInteger() ) < 0 ) common->Warning( "SDL_GL_SWAP_CONTROL not supported" ); // RB begin SDL_GetWindowSize( window, &glConfig.nativeScreenWidth, &glConfig.nativeScreenHeight ); // RB end glConfig.isFullscreen = ( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) == SDL_WINDOW_FULLSCREEN; #else glConfig.driverType = GLDRV_OPENGL3X; SDL_WM_SetCaption( GAME_NAME, GAME_NAME ); if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval.GetInteger() ) < 0 ) common->Warning( "SDL_GL_SWAP_CONTROL not supported" ); window = SDL_SetVideoMode( parms.width, parms.height, colorbits, flags ); if( !window ) { common->DPrintf( "Couldn't set GL mode %d/%d/%d: %s", channelcolorbits, tdepthbits, tstencilbits, SDL_GetError() ); continue; } glConfig.nativeScreenWidth = window->w; glConfig.nativeScreenHeight = window->h; glConfig.isFullscreen = ( window->flags & SDL_FULLSCREEN ) == SDL_FULLSCREEN; #endif common->Printf( "Using %d color bits, %d depth, %d stencil display\n", channelcolorbits, tdepthbits, tstencilbits ); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; // RB begin glConfig.displayFrequency = 60; glConfig.isStereoPixelFormat = parms.stereo; glConfig.multisamples = parms.multiSamples; glConfig.pixelAspect = 1.0f; // FIXME: some monitor modes may be distorted // should side-by-side stereo modes be consider aspect 0.5? // RB end break; } if( !window ) { common->Printf( "No usable GL mode found: %s", SDL_GetError() ); return false; } #ifdef __APPLE__ glewExperimental = GL_TRUE; #endif GLenum glewResult = glewInit(); if( GLEW_OK != glewResult ) { // glewInit failed, something is seriously wrong common->Printf( "^3GLimp_Init() - GLEW could not load OpenGL subsystem: %s", glewGetErrorString( glewResult ) ); } else { common->Printf( "Using GLEW %s\n", glewGetString( GLEW_VERSION ) ); } // DG: disable cursor, we have two cursors in menu (because mouse isn't grabbed in menu) SDL_ShowCursor( SDL_DISABLE ); // DG end return true; }
/* ==================== R_GetModeListForDisplay ==================== */ bool R_GetModeListForDisplay( const int requestedDisplayNum, idList<vidMode_t>& modeList ) { assert( requestedDisplayNum >= 0 ); modeList.Clear(); #if SDL_VERSION_ATLEAST(2, 0, 0) // DG: SDL2 implementation if( requestedDisplayNum >= SDL_GetNumVideoDisplays() ) { // requested invalid displaynum return false; } int numModes = SDL_GetNumDisplayModes( requestedDisplayNum ); if( numModes > 0 ) { for( int i = 0; i < numModes; i++ ) { SDL_DisplayMode m; int ret = SDL_GetDisplayMode( requestedDisplayNum, i, &m ); if( ret != 0 ) { common->Warning( "Can't get video mode no %i, because of %s\n", i, SDL_GetError() ); continue; } vidMode_t mode; mode.width = m.w; mode.height = m.h; mode.displayHz = m.refresh_rate ? m.refresh_rate : 60; // default to 60 if unknown (0) modeList.AddUnique( mode ); } if( modeList.Num() < 1 ) { common->Warning( "Couldn't get a single video mode for display %i, using default ones..!\n", requestedDisplayNum ); FillStaticVidModes( modeList ); } // sort with lowest resolution first modeList.SortWithTemplate( idSort_VidMode() ); } else { common->Warning( "Can't get Video Info, using default modes...\n" ); if( numModes < 0 ) { common->Warning( "Reason was: %s\n", SDL_GetError() ); } FillStaticVidModes( modeList ); } return true; // DG end #else // SDL 1 // DG: SDL1 only knows of one display - some functions rely on // R_GetModeListForDisplay() returning false for invalid displaynum to iterate all displays if( requestedDisplayNum >= 1 ) { return false; } // DG end const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); if( videoInfo == NULL ) { // DG: yes, this can actually fail, e.g. if SDL_Init( SDL_INIT_VIDEO ) wasn't called common->Warning( "Can't get Video Info, using default modes...\n" ); FillStaticVidModes( modeList ); return true; } SDL_Rect** modes = SDL_ListModes( videoInfo->vfmt, SDL_OPENGL | SDL_FULLSCREEN ); if( !modes ) { common->Warning( "Can't get list of available modes, using default ones...\n" ); FillStaticVidModes( modeList ); return true; } if( modes == ( SDL_Rect** ) - 1 ) { common->Printf( "Display supports any resolution\n" ); FillStaticVidModes( modeList ); return true; } int numModes; for( numModes = 0; modes[numModes]; numModes++ ); if( numModes > 1 ) { for( int i = 0; i < numModes; i++ ) { vidMode_t mode; mode.width = modes[i]->w; mode.height = modes[i]->h; mode.displayHz = 60; // FIXME; modeList.AddUnique( mode ); } // sort with lowest resolution first modeList.SortWithTemplate( idSort_VidMode() ); return true; } return false; #endif }
int System::GetNumDisplays () { return SDL_GetNumVideoDisplays (); }
extern "C" int main(int argcount, char* argvec[]) #endif { #if defined(__native_client__) std::cerr << "Running game_main" << std::endl; chdir("/frogatto"); { char buf[256]; const char* const res = getcwd(buf,sizeof(buf)); std::cerr << "Current working directory: " << res << std::endl; } #endif #if defined(_MSC_VER) std::shared_ptr<FILE> f_stderr = std::shared_ptr<FILE>(freopen ("stderr.txt", "wt", stderr), [](FILE* f){fclose(f); delete f;}); #endif #if defined(__APPLE__) && TARGET_OS_MAC chdir([[[NSBundle mainBundle] resourcePath] fileSystemRepresentation]); #endif #ifdef NO_STDERR std::freopen("/dev/null", "w", stderr); std::cerr.sync_with_stdio(true); #endif std::cerr << "Frogatto engine version " << preferences::version() << "\n"; LOG( "After print engine version" ); #if defined(TARGET_BLACKBERRY) chdir("app/native"); std::cout<< "Changed working directory to: " << getcwd(0, 0) << std::endl; #endif game_logic::init_callable_definitions(); std::string level_cfg = "titlescreen.cfg"; bool unit_tests_only = false, skip_tests = false; bool run_benchmarks = false; std::vector<std::string> benchmarks_list; std::string utility_program; std::vector<std::string> util_args; std::string server = "wesnoth.org"; #if defined(UTILITY_IN_PROC) bool create_utility_in_new_process = false; std::string utility_name; #endif bool is_child_utility = false; const char* profile_output = NULL; std::string profile_output_buf; #if defined(__ANDROID__) //monstartup("libapplication.so"); #endif std::string orig_level_cfg = level_cfg; std::string override_level_cfg = ""; int modules_loaded = 0; std::vector<std::string> argv; for(int n = 1; n < argcount; ++n) { #if defined(UTILITY_IN_PROC) std::string sarg(argvec[n]); if(sarg.compare(0, 15, "--utility-proc=") == 0) { create_utility_in_new_process = true; utility_name = "--utility-child=" + sarg.substr(15); } else { argv.push_back(argvec[n]); } #else argv.push_back(argvec[n]); #endif if(argv.size() >= 2 && argv[argv.size()-2] == "-NSDocumentRevisionsDebugMode" && argv.back() == "YES") { //XCode passes these arguments by default when debugging -- make sure they are ignored. argv.resize(argv.size()-2); } } std::cerr << "Build Options:"; for(auto bo : preferences::get_build_options()) { std::cerr << " " << bo; } std::cerr << std::endl; #if defined(UTILITY_IN_PROC) if(create_utility_in_new_process) { argv.push_back(utility_name); #if defined(_MSC_VER) // app name is ignored for windows, we get windows to tell us. is_child_utility = create_utility_process("", argv); #else is_child_utility = create_utility_process(argvec[0], argv); #endif if(!is_child_utility) { argv.pop_back(); } #if defined(_MSC_VER) atexit(terminate_utility_process); #endif } #endif if(sys::file_exists("./master-config.cfg")) { std::cerr << "LOADING CONFIGURATION FROM master-config.cfg" << std::endl; variant cfg = json::parse_from_file("./master-config.cfg"); if(cfg.is_map()) { if( cfg["id"].is_null() == false) { std::cerr << "SETTING MODULE PATH FROM master-config.cfg: " << cfg["id"].as_string() << std::endl; preferences::set_preferences_path_from_module(cfg["id"].as_string()); //XXX module::set_module_name(cfg["id"].as_string(), cfg["id"].as_string()); } if(cfg["arguments"].is_null() == false) { std::vector<std::string> additional_args = cfg["arguments"].as_list_string(); argv.insert(argv.begin(), additional_args.begin(), additional_args.end()); std::cerr << "ADDING ARGUMENTS FROM master-config.cfg:"; for(size_t n = 0; n < cfg["arguments"].num_elements(); ++n) { std::cerr << " " << cfg["arguments"][n].as_string(); } std::cerr << std::endl; } } } stats::record_program_args(argv); for(size_t n = 0; n < argv.size(); ++n) { const int argc = argv.size(); const std::string arg(argv[n]); std::string arg_name, arg_value; std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '='); if(equal != arg.end()) { arg_name = std::string(arg.begin(), equal); arg_value = std::string(equal+1, arg.end()); } if(arg_name == "--module") { if(load_module(arg_value, &argv) != 0) { std::cerr << "FAILED TO LOAD MODULE: " << arg_value << "\n"; return -1; } ++modules_loaded; } else if(arg == "--tests") { unit_tests_only = true; } } if(modules_loaded == 0 && !unit_tests_only) { if(load_module(DEFAULT_MODULE, &argv) != 0) { std::cerr << "FAILED TO LOAD MODULE: " << DEFAULT_MODULE << "\n"; return -1; } } preferences::load_preferences(); LOG( "After load_preferences()" ); // load difficulty settings after module, before rest of args. difficulty::manager(); for(size_t n = 0; n < argv.size(); ++n) { const size_t argc = argv.size(); const std::string arg(argv[n]); std::string arg_name, arg_value; std::string::const_iterator equal = std::find(arg.begin(), arg.end(), '='); if(equal != arg.end()) { arg_name = std::string(arg.begin(), equal); arg_value = std::string(equal+1, arg.end()); } std::cerr << "ARGS: " << arg << std::endl; if(arg.substr(0,4) == "-psn") { // ignore. } else if(arg_name == "--module") { // ignore already processed. } else if(arg_name == "--profile" || arg == "--profile") { profile_output_buf = arg_value; profile_output = profile_output_buf.c_str(); } else if(arg_name == "--utility" || arg_name == "--utility-child") { if(arg_name == "--utility-child") { is_child_utility = true; } utility_program = arg_value; for(++n; n < argc; ++n) { const std::string arg(argv[n]); util_args.push_back(arg); } break; } else if(arg == "--benchmarks") { run_benchmarks = true; } else if(arg_name == "--benchmarks") { run_benchmarks = true; benchmarks_list = util::split(arg_value); } else if(arg == "--tests") { // ignore as already processed. } else if(arg == "--no-tests") { skip_tests = true; } else if(arg_name == "--width") { std::string w(arg_value); preferences::set_actual_screen_width(boost::lexical_cast<int>(w)); } else if(arg == "--width" && n+1 < argc) { std::string w(argv[++n]); preferences::set_actual_screen_width(boost::lexical_cast<int>(w)); } else if(arg_name == "--height") { std::string h(arg_value); preferences::set_actual_screen_height(boost::lexical_cast<int>(h)); } else if(arg == "--height" && n+1 < argc) { std::string h(argv[++n]); preferences::set_actual_screen_height(boost::lexical_cast<int>(h)); } else if(arg_name == "--level") { override_level_cfg = arg_value; } else if(arg == "--level" && n+1 < argc) { override_level_cfg = argv[++n]; } else if(arg_name == "--host") { server = arg_value; } else if(arg == "--host" && n+1 < argc) { server = argv[++n]; } else if(arg == "--compiled") { preferences::set_load_compiled(true); #ifndef NO_EDITOR } else if(arg == "--edit") { preferences::set_edit_on_start(true); #endif } else if(arg == "--no-compiled") { preferences::set_load_compiled(false); #if defined(TARGET_PANDORA) } else if(arg == "--no-fbo") { preferences::set_fbo(false); } else if(arg == "--no-bequ") { preferences::set_bequ(false); #endif } else if(arg == "--help" || arg == "-h") { print_help(std::string(argvec[0])); return 0; } else { const bool res = preferences::parse_arg(argv[n].c_str()); if(!res) { std::cerr << "unrecognized arg: '" << arg << "'\n"; return -1; } } } checksum::manager checksum_manager; #ifndef NO_EDITOR sys::filesystem_manager fs_manager; #endif // NO_EDITOR preferences::expand_data_paths(); background_task_pool::manager bg_task_pool_manager; LOG( "After expand_data_paths()" ); std::cerr << "Preferences dir: " << preferences::user_data_path() << '\n'; //make sure that the user data path exists. if(!preferences::setup_preferences_dir()) { std::cerr << "cannot create preferences dir!\n"; } std::cerr << "\n"; const tbs::internal_server_manager internal_server_manager_scope(preferences::internal_tbs_server()); if(utility_program.empty() == false && test::utility_needs_video(utility_program) == false) { #if defined(UTILITY_IN_PROC) if(is_child_utility) { ASSERT_LOG(ipc::semaphore::create(shared_sem_name, 1) != false, "Unable to create shared semaphore: " << errno); std::cerr.sync_with_stdio(true); } #endif test::run_utility(utility_program, util_args); return 0; } #if defined(TARGET_PANDORA) EGL_Open(); #endif #if defined(__ANDROID__) std::freopen("stdout.txt","w",stdout); std::freopen("stderr.txt","w",stderr); std::cerr.sync_with_stdio(true); #endif LOG( "Start of main" ); if(!skip_tests && !test::run_tests()) { return -1; } if(unit_tests_only) { return 0; } #if !defined(__native_client__) Uint32 sdl_init_flags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; #if defined(_WINDOWS) || TARGET_OS_IPHONE sdl_init_flags |= SDL_INIT_TIMER; #endif if(SDL_Init(sdl_init_flags) < 0) { std::cerr << "could not init SDL\n"; return -1; } LOG( "After SDL_Init" ); #endif #ifdef TARGET_OS_HARMATTAN g_type_init(); #endif i18n::init (); LOG( "After i18n::init()" ); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); #if TARGET_OS_IPHONE || defined(TARGET_BLACKBERRY) || defined(__ANDROID__) //on the iPhone and PlayBook, try to restore the auto-save if it exists if(sys::file_exists(preferences::auto_save_file_path()) && sys::read_file(std::string(preferences::auto_save_file_path()) + ".stat") == "1") { level_cfg = "autosave.cfg"; sys::write_file(std::string(preferences::auto_save_file_path()) + ".stat", "0"); } #endif if(override_level_cfg.empty() != true) { level_cfg = override_level_cfg; orig_level_cfg = level_cfg; } #if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(USE_SHADERS) wm.create_window(preferences::actual_screen_width(), preferences::actual_screen_height(), 0, (preferences::resizable() ? SDL_RESIZABLE : 0) | (preferences::fullscreen() ? SDL_FULLSCREEN : 0)); #else #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR int width, height; iphone_screen_res(&width, &height); preferences::set_actual_screen_width(width); preferences::set_actual_screen_height(height); int multiplier = 2; if (width > 320) { //preferences::set_use_pretty_scaling(true); multiplier = 1; } preferences::set_virtual_screen_width(height*multiplier); preferences::set_virtual_screen_height(width*multiplier); preferences::set_control_scheme(height % 1024 ? "iphone_2d" : "ipad_2d"); SDL_WindowID windowID = SDL_CreateWindow (NULL, 0, 0, preferences::actual_screen_width(), preferences::actual_screen_height(), SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS); if (windowID == 0) { std::cerr << "Could not create window: " << SDL_GetError() << "\n"; return -1; } // if (SDL_GL_CreateContext(windowID) == 0) { // std::cerr << "Could not create GL context: " << SDL_GetError() << "\n"; // return -1; // } if (SDL_CreateRenderer(windowID, -1, 0) != 0) { std::cerr << "Could not create renderer\n"; return -1; } #else #ifdef TARGET_OS_HARMATTAN SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGLES | SDL_FULLSCREEN) == NULL) { std::cerr << "could not set video mode\n"; return -1; } preferences::init_oes(); SDL_ShowCursor(0); #else #if defined(TARGET_PANDORA) if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),16,SDL_FULLSCREEN) == NULL) { std::cerr << "could not set video mode\n"; return -1; } EGL_Init(); preferences::init_oes(); #elif defined(TARGET_TEGRA) //if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,preferences::resizable() ? SDL_RESIZABLE : 0|preferences::fullscreen() ? SDL_FULLSCREEN : 0) == NULL) { if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_FULLSCREEN) == NULL) { std::cerr << "could not set video mode\n"; return -1; } EGL_Init(); preferences::init_oes(); #elif defined(TARGET_BLACKBERRY) if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|SDL_FULLSCREEN) == NULL) { std::cerr << "could not set video mode\n"; return -1; } preferences::init_oes(); #elif defined(__ANDROID__) #if SDL_VERSION_ATLEAST(2, 0, 0) int num_video_displays = SDL_GetNumVideoDisplays(); SDL_Rect r; if(num_video_displays < 0) { std::cerr << "no video displays available" << std::endl; return -1; } if(SDL_GetDisplayBounds(0, &r) < 0) { preferences::set_actual_screen_width(r.w); preferences::set_actual_screen_height(r.h); if(r.w < 640) { preferences::set_virtual_screen_width(r.w*2); preferences::set_virtual_screen_height(r.h*2); } else { preferences::set_virtual_screen_width(r.w); preferences::set_virtual_screen_height(r.h); } preferences::set_control_scheme(r.h >= 1024 ? "ipad_2d" : "android_med"); } #else SDL_Rect** r = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL); if( r != (SDL_Rect**)0 && r != (SDL_Rect**)-1 ) { preferences::set_actual_screen_width(r[0]->w); preferences::set_actual_screen_height(r[0]->h); if(r[0]->w < 640) { preferences::set_virtual_screen_width(r[0]->w*2); preferences::set_virtual_screen_height(r[0]->h*2); } else { preferences::set_virtual_screen_width(r[0]->w); preferences::set_virtual_screen_height(r[0]->h); } preferences::set_control_scheme(r[0]->h >= 1024 ? "ipad_2d" : "android_med"); } #endif #if SDL_VERSION_ATLEAST(2, 0, 0) if(!graphics::set_video_mode(preferences::actual_screen_width(), preferences::actual_screen_height())) { #else if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_FULLSCREEN|SDL_OPENGL) == NULL) { #endif std::cerr << "could not set video mode\n"; return -1; } #elif defined(__native_client__) SDL_Rect** r = SDL_ListModes(NULL, SDL_OPENGL); std::cerr << "Video modes"; if(r == (SDL_Rect**)0) { std::cerr << "No modes available"; return -1; } if(r == (SDL_Rect**)-1) { std::cerr << "All modes available"; } else { for(int i = 0; r[i]; ++i) { std::cerr << r[i]->w << r[i]->h << std::endl; } } if (SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,0) == NULL) { std::cerr << "could not set video mode\n"; return -1; } #else #if SDL_VERSION_ATLEAST(2, 0, 0) if(preferences::auto_size_window()) { const SDL_DisplayMode mode = graphics::set_video_mode_auto_select(); preferences::set_actual_screen_width(mode.w); preferences::set_actual_screen_height(mode.h); preferences::set_virtual_screen_width(mode.w); preferences::set_virtual_screen_height(mode.h); } else if(!graphics::set_video_mode(preferences::actual_screen_width(), preferences::actual_screen_height(), SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL)) { #else if(SDL_SetVideoMode(preferences::actual_screen_width(),preferences::actual_screen_height(),0,SDL_OPENGL|(preferences::resizable() ? SDL_RESIZABLE : 0)|(preferences::fullscreen() ? SDL_FULLSCREEN : 0)) == NULL) { #endif std::cerr << "could not set video mode\n"; return -1; } #ifndef __APPLE__ graphics::surface wm_icon = graphics::surface_cache::get("window-icon.png"); if(!wm_icon.null()) { #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetWindowIcon(graphics::get_window(), wm_icon.get()); #else SDL_WM_SetIcon(wm_icon, NULL); #endif } #endif // __APPLE__ #endif #endif #endif #endif #if !SDL_VERSION_ATLEAST(2, 0, 0) && defined(__GLEW_H__) GLenum glew_status = glewInit(); ASSERT_EQ(glew_status, GLEW_OK); #endif #if defined(USE_SHADERS) if(glCreateShader == NULL) { const GLubyte* glstrings; if(glGetString != NULL && (glstrings = glGetString(GL_VERSION)) != NULL) { std::cerr << "OpenGL version: " << reinterpret_cast<const char *>(glstrings) << std::endl; } std::cerr << "glCreateShader is NULL. Check that your current video card drivers support " << "an OpenGL version >= 2. Exiting." << std::endl; return 0; } // Has to happen after the call to glewInit(). gles2::init_default_shader(); #endif // srand(time(NULL)); const stats::manager stats_manager; #ifndef NO_EDITOR const external_text_editor::manager editor_manager; #endif // NO_EDITOR #if defined(USE_BOX2D) box2d::manager b2d_manager; #endif std::cerr << std::endl; const GLubyte* glstrings; if((glstrings = glGetString(GL_VENDOR)) != NULL) { std::cerr << "OpenGL vendor: " << reinterpret_cast<const char *>(glstrings) << std::endl; } else { GLenum err = glGetError(); std::cerr << "Error in vendor string: " << std::hex << err << std::endl; } if((glstrings = glGetString(GL_VERSION)) != NULL) { std::cerr << "OpenGL version: " << reinterpret_cast<const char *>(glstrings) << std::endl; } else { GLenum err = glGetError(); std::cerr << "Error in version string: " << std::hex << err << std::endl; } if((glstrings = glGetString(GL_EXTENSIONS)) != NULL) { std::cerr << "OpenGL extensions: " << reinterpret_cast<const char *>(glstrings) << std::endl; } else { GLenum err = glGetError(); std::cerr << "Error in extensions string: " << std::hex << err << std::endl; } #ifdef GL_SHADING_LANGUAGE_VERSION if((glstrings = glGetString(GL_SHADING_LANGUAGE_VERSION)) != NULL) { std::cerr << "GLSL Version: " << reinterpret_cast<const char *>(glstrings) << std::endl; } else { GLenum err = glGetError(); std::cerr << "Error in GLSL string: " << std::hex << err << std::endl; } #endif std::cerr << std::endl; GLint stencil_bits = 0; glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); std::cerr << "Stencil bits: " << stencil_bits << std::endl; #if defined(USE_SHADERS) #if !defined(GL_ES_VERSION_2_0) GLfloat min_pt_sz; glGetFloatv(GL_POINT_SIZE_MIN, &min_pt_sz); GLfloat max_pt_sz; glGetFloatv(GL_POINT_SIZE_MAX, &max_pt_sz); std::cerr << "Point size range: " << min_pt_sz << " < size < " << max_pt_sz << std::endl; glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif #endif glShadeModel(GL_SMOOTH); glEnable(GL_BLEND); #if !defined(USE_SHADERS) glEnable(GL_TEXTURE_2D); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); #endif glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); std::cerr << "JOYSTICKS: " << SDL_NumJoysticks() << "\n"; const load_level_manager load_manager; { //manager scope const font::manager font_manager; const sound::manager sound_manager; #if !defined(__native_client__) const joystick::manager joystick_manager; #endif graphics::texture::manager texture_manager; #ifndef NO_EDITOR editor::manager editor_manager; #endif variant preloads; loading_screen loader; try { variant gui_node = json::parse_from_file(preferences::load_compiled() ? "data/compiled/gui.cfg" : "data/gui.cfg"); gui_section::init(gui_node); loader.draw_and_increment(_("Initializing GUI")); framed_gui_element::init(gui_node); sound::init_music(json::parse_from_file("data/music.cfg")); graphical_font::init_for_locale(i18n::get_locale()); preloads = json::parse_from_file("data/preload.cfg"); int preload_items = preloads["preload"].num_elements(); loader.set_number_of_items(preload_items+7); // 7 is the number of items that will be loaded below custom_object::init(); loader.draw_and_increment(_("Initializing custom object functions")); init_custom_object_functions(json::parse_from_file("data/functions.cfg")); loader.draw_and_increment(_("Initializing textures")); loader.load(preloads); loader.draw_and_increment(_("Initializing tiles")); tile_map::init(json::parse_from_file("data/tiles.cfg")); game_logic::formula_object::load_all_classes(); } catch(const json::parse_error& e) { std::cerr << "ERROR PARSING: " << e.error_message() << "\n"; return 0; } loader.draw(_("Loading level")); #if defined(__native_client__) while(1) { } #endif #if defined(__APPLE__) && !(TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE) && !defined(USE_SHADERS) GLint swapInterval = 1; CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &swapInterval); #endif loader.finish_loading(); //look to see if we got any quit events while loading. { SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) { return 0; } } } formula_profiler::manager profiler(profile_output); #ifdef USE_SHADERS texture_frame_buffer::init(preferences::actual_screen_width(), preferences::actual_screen_height()); #else texture_frame_buffer::init(); #endif if(run_benchmarks) { if(benchmarks_list.empty() == false) { test::run_benchmarks(&benchmarks_list); } else { test::run_benchmarks(); } return 0; } else if(utility_program.empty() == false && test::utility_needs_video(utility_program) == true) { test::run_utility(utility_program, util_args); return 0; } bool quit = false; while(!quit && !show_title_screen(level_cfg)) { boost::intrusive_ptr<level> lvl(load_level(level_cfg)); #if !defined(__native_client__) //see if we're loading a multiplayer level, in which case we //connect to the server. multiplayer::manager mp_manager(lvl->is_multiplayer()); if(lvl->is_multiplayer()) { multiplayer::setup_networked_game(server); } if(lvl->is_multiplayer()) { last_draw_position() = screen_position(); std::string level_cfg = "waiting-room.cfg"; boost::intrusive_ptr<level> wait_lvl(load_level(level_cfg)); wait_lvl->finish_loading(); wait_lvl->set_multiplayer_slot(0); if(wait_lvl->player()) { wait_lvl->player()->set_current_level(level_cfg); } wait_lvl->set_as_current_level(); level_runner runner(wait_lvl, level_cfg, orig_level_cfg); multiplayer::sync_start_time(*lvl, boost::bind(&level_runner::play_cycle, &runner)); lvl->set_multiplayer_slot(multiplayer::slot()); } #endif last_draw_position() = screen_position(); assert(lvl.get()); if(!lvl->music().empty()) { sound::play_music(lvl->music()); } if(lvl->player() && level_cfg != "autosave.cfg") { lvl->player()->set_current_level(level_cfg); lvl->player()->get_entity().save_game(); } set_scene_title(lvl->title()); try { quit = level_runner(lvl, level_cfg, orig_level_cfg).play_level(); level_cfg = orig_level_cfg; } catch(multiplayer_exception&) { } } level::clear_current_level(); } //end manager scope, make managers destruct before calling SDL_Quit // controls::debug_dump_controls(); #if defined(TARGET_PANDORA) || defined(TARGET_TEGRA) EGL_Destroy(); #endif #if SDL_VERSION_ATLEAST(2, 0, 0) // Be nice and destroy the GL context and the window. graphics::set_video_mode(0, 0, CLEANUP_WINDOW_CONTEXT); #elif defined(USE_SHADERS) wm.destroy_window(); #endif SDL_Quit(); preferences::save_preferences(); std::cerr << SDL_GetError() << "\n"; #if !defined(_MSC_VER) && defined(UTILITY_IN_PROC) if(create_utility_in_new_process) { terminate_utility_process(); } #endif #ifdef _MSC_VER ExitProcess(0); #endif std::set<variant*> loading; swap_variants_loading(loading); if(loading.empty() == false) { fprintf(stderr, "Illegal object: %p\n", (void*)(*loading.begin())->as_callable_loading()); ASSERT_LOG(false, "Unresolved unserialized objects: " << loading.size()); } return 0; }
/*GLOBAL FUNCTIONS*/ void NLF_screen_init() { int flags; int aux; char *str; int sdlRet; NLF_bool saydone; /*INITIALIZING SDL_IMAGE*/ flags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF; if((IMG_Init(flags) & flags) != flags) { flags = IMG_INIT_TIF; if((IMG_Init(flags) & flags) != flags) { printf("\tCan't initialize SDL_image\nSDL_IMAGE ERROR: %s\n", IMG_GetError()); printf("\ttraing for TIF format... "); flags = IMG_INIT_TIF; if((IMG_Init(flags) & flags) != flags) { printf("fail\n\tSDL_IMAGE ERROR: %s\n", IMG_GetError()); tifFlag = NLF_True; }else{ printf("done\n"); tifFlag = NLF_False; } printf("\ttraing for PNG format... \n"); flags = IMG_INIT_PNG; if((IMG_Init(flags) & flags) != flags) { printf("fail\n\tSDL_IMAGE ERROR: %s\n", IMG_GetError()); pngFlag = NLF_True; }else{ printf("done\n"); pngFlag = NLF_False; } printf("\ttraing for JPG format... \n"); flags = IMG_INIT_JPG; if((IMG_Init(flags) & flags) != flags) { printf("fail\n\tSDL_IMAGE ERROR: %s\n", IMG_GetError()); jpgFlag = NLF_True; }else{ printf("done\n"); jpgFlag = NLF_False; } if(jpgFlag == NLF_False && pngFlag == NLF_False && tifFlag == NLF_False) { printf("\tScreen module initialization has failed.\n"); str = SDL_GetError(); printf("\tSDL_ERROR: %s\n", str); printf("\tAborting\n"); NLF_error_make_file_crash_report(NLF_ErrorSDLImageInitializer, "Screen module initialization has failed", "SDL Error: ", str, NULL); exit(NLF_ErrorSDLImageInitializer); } } }else{ jpgFlag = NLF_True; pngFlag = NLF_True; tifFlag = NLF_True; } /************************/ /*SETTING GLOBALS VARIABLES*/ ///GETTING DISPLAY INFORMATIONS aux = SDL_GetNumVideoDisplays(); if(aux < 0) { //error case printf("Fail trying to get video display number.\n"); str = SDL_GetError(); printf("\tSDL_ERROR: %s\n", str); printf("\tAborting\n"); NLF_error_make_file_crash_report(NLF_ErrorSDLProblem, "Fail trying to get video display number", "SDL Error: ", str, NULL); exit(aux); }else{ displayInUse = 0; printf("\n\t%d Displays avaliable, piking the number %d as pattern\n", aux, displayInUse + 1); } displayInfoUnknown = NLF_False; for(aux = 0; aux < 3; aux++) { saydone = NLF_False; if(aux == 0) sdlRet = SDL_GetCurrentDisplayMode(displayInUse, &videoMode); else if(aux == 1) sdlRet = SDL_GetDisplayMode(displayInUse, displayInUse, &videoMode); else if(aux == 2) sdlRet = SDL_GetWindowDisplayMode(displayInUse, &videoMode); if(sdlRet != 0) { if(aux == 2) { //totally unsuccessful case printf("\tSorry, impossible to get display #%d mode:\n\tSDL_ERROR: %s\n", displayInUse + 1, SDL_GetError()); printf("\tstandard 800x600 will be set\n"); displayInfoUnknown = NLF_True; }else{ printf("\tSorry, could not get display #%d mode:\n\tSDL_ERROR: %s\n", displayInUse + 1, SDL_GetError()); printf("\ttrying another way...\n"); saydone = NLF_True; } }else{ printf("\tcurrent display(%d) mode detected %dx%dpx @ %dhz. \n", displayInUse + 1, videoMode.w, videoMode.h, videoMode.refresh_rate); if(videoMode.w == 0 || videoMode.h == 0 || videoMode.refresh_rate == 0) { printf("\tSorry, could not get all display #%d mode information\n", displayInUse + 1); printf("\ttrying another way...\n"); saydone = NLF_True; }else{ printf("\tdone\n"); aux = 3; } } } ///**************************** /*SETTING SOME GLOBAL VARIABLES*/ camera.x = 0; camera.y = 0; if(displayInfoUnknown == NLF_False) { camera.w = 800; camera.h = 600; }else{ camera.w = videoMode.w; camera.h = videoMode.h; } screens = NULL; currentFPS = 0; //there's just no need to the FPS be greater then the display refresh rate (videoMode.refresh_rate >= 60 || videoMode.refresh_rate == 0) ? (idealFPS = 60): (idealFPS = videoMode.refresh_rate); /*******************************/ ///CREATING WINDOW SET window = SDL_CreateWindow("NorthLionFramework Game", 0, 0, camera.w, camera.h, SDL_WINDOW_BORDERLESS | SDL_WINDOW_MAXIMIZED); if(window == NULL) { printf("\tCould not craete the window\n"); str = SDL_GetError(); printf("\tSDL_ERROR: %s\n", str); printf("\tAborting\n"); NLF_error_make_file_crash_report(NLF_ErrorSDLProblem, "Could not craete the window", "SDL Error: ", str, NULL); exit(NLF_ErrorSDLProblem); //I don't know what to do else but quiting... you know, we need a window .-. } //this loop will try to initialize the render the best way possible for(aux = 0; aux < 4 && window_rederer == NULL; aux++) { switch(aux) { case 0: flags = SDL_RENDERER_SOFTWARE | SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE; break; case 1: flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE; break; case 2: flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; break; case 3: flags = SDL_RENDERER_ACCELERATED; break; } if(aux > 0) printf("\ttrying flags(%d)... ", flags); window_rederer = SDL_CreateRenderer(window, -1, flags); if(window_rederer == NULL) { if(aux > 0) printf("fail\n"); if(aux != 3) { printf("\tCould not create render with all flags(%d)\n", flags); printf("\tSDL_ERROR: %s\n", SDL_GetError()); }else{ printf("\tIt was impossible to create the render.\n"); str = SDL_GetError(); printf("\tSDL_ERROR: %s\n", str); printf("\tAborting\n"); NLF_error_make_file_crash_report(NLF_ErrorSDLProblem, "It was impossible to create the render", "SDL Error: ", str, NULL); exit(NLF_ErrorSDLProblem); //I don't know what to do else but quiting... you know, we also need a renderer .-. } }else{ if(aux > 0) printf("done\n"); } } if(aux > 0) ///******************* ///GETTING VIDEO CARD INFORMATION aux = 0; if(SDL_GetRendererInfo(window_rederer, &rendererInfo) < 0) { printf("\tCould not get information about the renderer.\n"); printf("\tSDL_ERROR: %s\n", SDL_GetError()); rendererInfoUnknown = NLF_True; }else{ aux = 1; rendererInfoUnknown = NLF_False; } if(SDL_GetRenderDriverInfo(displayInUse, &rendererDriverInfo) < 0) { printf("\tCould not get information about the renderer driver.\n"); printf("\tSDL_ERROR: %s\n", SDL_GetError()); rendererDriverInfoUnkown = NLF_True; }else{ aux = 1; rendererDriverInfoUnkown = NLF_False; } ///****************************** /***************************/ }
/* =================== GLimp_Init =================== */ bool GLimp_Init(glimpParms_t parms) { common->Printf( "Initializing OpenGL subsystem\n" ); GLimp_PreInit(); Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; if (parms.fullScreen) flags |= SDL_WINDOW_FULLSCREEN; int colorbits = 24; int depthbits = 24; int stencilbits = 8; for (int i = 0; i < 16; i++) { // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ((i % 4) == 0 && i) { // one pass, reduce switch (i / 4) { case 2 : if (colorbits == 24) colorbits = 16; break; case 1 : if (depthbits == 24) depthbits = 16; else if (depthbits == 16) depthbits = 8; case 3 : if (stencilbits == 24) stencilbits = 16; else if (stencilbits == 16) stencilbits = 8; } } int tcolorbits = colorbits; int tdepthbits = depthbits; int tstencilbits = stencilbits; if ((i % 4) == 3) { // reduce colorbits if (tcolorbits == 24) tcolorbits = 16; } if ((i % 4) == 2) { // reduce depthbits if (tdepthbits == 24) tdepthbits = 16; else if (tdepthbits == 16) tdepthbits = 8; } if ((i % 4) == 1) { // reduce stencilbits if (tstencilbits == 24) tstencilbits = 16; else if (tstencilbits == 16) tstencilbits = 8; else tstencilbits = 0; } int channelcolorbits = 4; if (tcolorbits == 24) channelcolorbits = 8; SDL_GL_SetAttribute (SDL_GL_RED_SIZE, channelcolorbits); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, channelcolorbits); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, channelcolorbits); if (r_waylandcompat.GetBool()) SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); else SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, channelcolorbits); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, tdepthbits); SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, tstencilbits); SDL_GL_SetAttribute(SDL_GL_STEREO, parms.stereo ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, parms.multiSamples ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, parms.multiSamples); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if( r_useOpenGL32.GetInteger() > 0 ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 ); if( r_useOpenGL32.GetInteger() > 1 ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); } else { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY ); } if( r_debugContext.GetBool() ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); } } int windowPos = SDL_WINDOWPOS_UNDEFINED; if( parms.fullScreen > 0 ) { if( parms.fullScreen > SDL_GetNumVideoDisplays() ) { common->Warning( "Couldn't set display to num %i because we only have %i displays", parms.fullScreen, SDL_GetNumVideoDisplays() ); } else { // -1 because SDL starts counting displays at 0, while parms.fullScreen starts at 1 windowPos = SDL_WINDOWPOS_UNDEFINED_DISPLAY( ( parms.fullScreen - 1 ) ); } } // TODO: if parms.fullScreen == -1 there should be a borderless window spanning multiple displays /* * NOTE that this implicitly handles parms.fullScreen == -2 (from r_fullscreen -2) meaning * "do fullscreen, but I don't care on what monitor", at least on my box it's the monitor with * the mouse cursor. */ // Destroy existing state if it exists if( SDL_glContext != NULL ) { SDL_GL_DeleteContext( SDL_glContext ); SDL_glContext = NULL; } if( SDL_window != NULL ) { SDL_GetWindowPosition( SDL_window, &windowPos, &windowPos ); common->DPrintf( "Existing window at %dx%d before being destroyed\n", windowPos, windowPos ); SDL_DestroyWindow( SDL_window ); SDL_window = NULL; } //------------------------SETTERS SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 8); if (r_waylandcompat.GetBool()) SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); else SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_STEREO, parms.stereo ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, parms.multiSamples ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, parms.multiSamples); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if( r_useOpenGL32.GetInteger() > 0 ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 ); if( r_useOpenGL32.GetInteger() > 1 ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); } else { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY ); } if( r_debugContext.GetBool() ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); } } if( parms.fullScreen > 0 ) { if( parms.fullScreen > SDL_GetNumVideoDisplays() ) { common->Warning( "Couldn't set display to num %i because we only have %i displays", parms.fullScreen, SDL_GetNumVideoDisplays() ); } else { // -1 because SDL starts counting displays at 0, while parms.fullScreen starts at 1 windowPos = SDL_WINDOWPOS_UNDEFINED_DISPLAY( ( parms.fullScreen - 1 ) ); } } // TODO: if parms.fullScreen == -1 there should be a borderless window spanning multiple displays /* * NOTE that this implicitly handles parms.fullScreen == -2 (from r_fullscreen -2) meaning * "do fullscreen, but I don't care on what monitor", at least on my box it's the monitor with * the mouse cursor. */ // Destroy existing state if it exists if( SDL_glContext != NULL ) { SDL_GL_DeleteContext( SDL_glContext ); SDL_glContext = NULL; } if( SDL_window != NULL ) { SDL_GetWindowPosition( SDL_window, &windowPos, &windowPos ); common->DPrintf( "Existing window at %dx%d before being destroyed\n", windowPos, windowPos ); SDL_DestroyWindow( SDL_window ); SDL_window = NULL; } #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_window = SDL_CreateWindow(GAME_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, parms.width, parms.height, flags); if (!SDL_window) { common->DPrintf("Couldn't set GL mode %d/%d/%d: %s", channelcolorbits, tdepthbits, tstencilbits, SDL_GetError()); continue; } SDL_glContext = SDL_GL_CreateContext(SDL_window); if (!SDL_glContext) { common->DPrintf( "SDL_GL_CreateContext failed: %s\n", SDL_GetError( ) ); return false; } if( SDL_GL_MakeCurrent( SDL_window, SDL_glContext ) < 0 ) { common->DPrintf( "SDL_GL_MakeCurrent failed: %s\n", SDL_GetError( ) ); return false; } if (SDL_GL_SetSwapInterval(r_swapInterval.GetInteger()) < 0) common->Warning("SDL_GL_SWAP_CONTROL not supported"); SDL_GetWindowSize( SDL_window, &glConfig.vidWidth, &glConfig.vidHeight ); glConfig.isFullscreen = (SDL_GetWindowFlags( SDL_window ) & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN; #else SDL_WM_SetCaption(GAME_NAME, GAME_NAME); if (SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, r_swapInterval.GetInteger()) < 0) common->Warning("SDL_GL_SWAP_CONTROL not supported"); SDL_window = SDL_SetVideoMode(parms.width, parms.height, colorbits, flags); if (!SDL_window) { common->DPrintf("Couldn't set GL mode %d/%d/%d: %s", channelcolorbits, tdepthbits, tstencilbits, SDL_GetError()); continue; } glConfig.isFullscreen = (SDL_window->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN; #endif common->Printf("Using %d color bits, %d depth, %d stencil display\n", channelcolorbits, tdepthbits, tstencilbits); glConfig.colorBits = tcolorbits; glConfig.depthBits = tdepthbits; glConfig.stencilBits = tstencilbits; // FIXME kortemik? glConfig.displayFrequency = 0; // make sure cursor is not visible and grab window focus SDL_ShowCursor( SDL_DISABLE ); SDL_SetWindowGrab( SDL_window, SDL_TRUE ); break; } if (!SDL_window) { common->Warning("No usable GL mode found: %s", SDL_GetError()); return false; } return true; }
int main(int argc, char **argv) { if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return -1; } if(TTF_Init() < 0) { fprintf(stderr, "Couldn't initialize font rendering: %s\n", TTF_GetError()); return -1; } int width = 800; int height = 600; Uint32 frameRate = BASE_FRAME_RATE_MS; SDL_bool vsync = SDL_FALSE; #if SDL_MAJOR_VERSION == 2 SDL_DisplayMode current; for(int i = 0; i < SDL_GetNumVideoDisplays(); ++i){ if(SDL_GetCurrentDisplayMode(i, ¤t) != 0) fprintf(stderr, "Couldn't get display mode: %s\n", SDL_GetError()); else { printf("Display %d is %dx%d\n", i, current.w, current.h); width = current.w; height = current.h; } } Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC; if(argc > 1) { if(strncmp(argv[1], "-novsync", 8) == 0) flags &= ~SDL_RENDERER_PRESENTVSYNC; if(strncmp(argv[1], "-software", 9) == 0) flags = SDL_RENDERER_SOFTWARE; char *n = strchr(argv[1], '='); if(n) { n++; frameRate = strtoul(n, 0, 0); } } SDL_Window *window = SDL_CreateWindow(argv[0], SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width + GetIntelOffset(), height, SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN); SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, flags); SDL_ShowCursor(SDL_DISABLE); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); SDL_DisableScreenSaver(); SDL_RendererInfo info; if(SDL_GetRendererInfo(renderer, &info) == 0) { printf("Using video driver: %s with renderer %s\n", SDL_GetCurrentVideoDriver(), info.name); if(info.flags & SDL_RENDERER_SOFTWARE) printf("*** Using SDL_RENDERER_SOFTWARE\n"); if(info.flags & SDL_RENDERER_ACCELERATED) printf("*** Using SDL_RENDERER_ACCELERATED\n"); if(info.flags & SDL_RENDERER_PRESENTVSYNC) { printf("*** Using SDL_RENDERER_PRESENTVSYNC\n"); vsync = SDL_TRUE; } if(info.flags & SDL_RENDERER_TARGETTEXTURE) printf("*** Using SDL_RENDERER_TARGETTEXTURE\n"); } #else const SDL_VideoInfo *pVideoInfo = SDL_GetVideoInfo(); if(pVideoInfo == 0) { fprintf(stderr, "Couldn't get display information: %s\n", SDL_GetError()); exit(1); } printf("Display is %dx%d\n", pVideoInfo->current_w, pVideoInfo->current_h); width = pVideoInfo->current_w; height = pVideoInfo->current_h; SDL_Surface *screen = SDL_SetVideoMode(width, height, pVideoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN); if(screen == 0) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_ShowCursor(SDL_DISABLE); #endif TTF_Font *font = TTF_OpenFont("AlteHaasGroteskBold.ttf", 60); if(font == 0) { fprintf(stderr, "Can't open font for stats: %s", TTF_GetError()); goto cleanup; } SDL_Event event; SDL_bool m_run = SDL_TRUE; Uint32 lastFrame = 0; float fps = 0.0f; SDL_Color foregroundColor = { 0xff, 0xff, 0 }; char tmp[64]; int delta = 1; int position = 0; while(m_run) { while(SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: if(event.key.keysym.sym == SDLK_ESCAPE) m_run = SDL_FALSE; break; case SDL_QUIT: m_run = SDL_FALSE; break; default: break; } } Uint32 start = SDL_GetTicks(); #if SDL_MAJOR_VERSION == 2 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); SDL_RenderClear(renderer); #else SDL_FillRect(screen, 0, 0); #endif snprintf(tmp, sizeof(tmp), "Current fps = %.1f", fps); SDL_Surface *textSurface = TTF_RenderText_Solid(font, tmp, foregroundColor); if(textSurface) { #if SDL_MAJOR_VERSION == 2 SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface); #endif SDL_Rect location; location.h = textSurface->h; location.w = textSurface->w; location.x = position; location.y = height / 2 - textSurface->h / 2; #if SDL_MAJOR_VERSION == 1 SDL_BlitSurface(textSurface, 0, screen, &location); #endif SDL_FreeSurface(textSurface); position += delta; if(position >= width - textSurface->w || position <= 0) delta *= -1; #if SDL_MAJOR_VERSION == 2 if(textTexture) { SDL_RenderCopy(renderer, textTexture, 0, &location); SDL_DestroyTexture(textTexture); } #endif } #if SDL_MAJOR_VERSION == 2 SDL_RenderPresent(renderer); #else SDL_Flip(screen); #endif Uint32 end = SDL_GetTicks(); Uint32 elapsed = end - lastFrame; // delay for the remainder of the base rate so we keep a decent frame rate if there's no vsync if(vsync == SDL_FALSE && frameRate > elapsed) SDL_Delay(frameRate - elapsed); if(elapsed > frameRate * 3) { struct timeb tp; ftime(&tp); time_t now; struct tm *ti; char buf[255]; time(&now); ti = localtime(&now); strftime(buf, sizeof(buf), "%I:%M:%S", ti); printf("%s.%d: Frame took %ums\n", buf, tp.millitm, elapsed); } // remember now as the starting point for the next frame lastFrame = SDL_GetTicks(); // update statistics elapsed = lastFrame - start; fps = 1000.0f / (float)elapsed; //printf("Current frame rate is %6.3f fps (%ums) \r", fps, elapsed); } printf("\n"); cleanup: #if SDL_MAJOR_VERSION == 2 SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); #else SDL_FreeSurface(screen); #endif TTF_Quit(); SDL_Quit(); return 0; }
SDL_bool CommonInit(CommonState * state) { int i, j, m, n; SDL_DisplayMode fullscreen_mode; if (state->flags & SDL_INIT_VIDEO) { if (state->verbose & VERBOSE_VIDEO) { n = SDL_GetNumVideoDrivers(); if (n == 0) { fprintf(stderr, "No built-in video drivers\n"); } else { fprintf(stderr, "Built-in video drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetVideoDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_VideoInit(state->videodriver, 0) < 0) { fprintf(stderr, "Couldn't initialize video driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Video driver: %s\n", SDL_GetCurrentVideoDriver()); } if (state->verbose & VERBOSE_MODES) { SDL_DisplayMode mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; n = SDL_GetNumVideoDisplays(); fprintf(stderr, "Number of displays: %d\n", n); for (i = 0; i < n; ++i) { fprintf(stderr, "Display %d:\n", i); SDL_SelectVideoDisplay(i); SDL_GetDesktopDisplayMode(&mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Current mode: %dx%d@%dHz, %d bits-per-pixel\n", mode.w, mode.h, mode.refresh_rate, bpp); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } /* Print available fullscreen video modes */ m = SDL_GetNumDisplayModes(); if (m == 0) { fprintf(stderr, "No available fullscreen video modes\n"); } else { fprintf(stderr, " Fullscreen video modes:\n"); for (j = 0; j < m; ++j) { SDL_GetDisplayMode(j, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Mode %d: %dx%d@%dHz, %d bits-per-pixel\n", j, mode.w, mode.h, mode.refresh_rate, bpp); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } } } } } SDL_SelectVideoDisplay(state->display); if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); if (n == 0) { fprintf(stderr, "No built-in render drivers\n"); } else { fprintf(stderr, "Built-in render drivers:\n"); for (i = 0; i < n; ++i) { SDL_GetRenderDriverInfo(i, &info); PrintRenderer(&info); } } } switch (state->depth) { case 8: fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; break; case 15: fullscreen_mode.format = SDL_PIXELFORMAT_BGR555; break; case 16: default: fullscreen_mode.format = SDL_PIXELFORMAT_ABGR1555; break; /* NDS default: fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; break;*/ } fullscreen_mode.w = state->window_w; fullscreen_mode.h = state->window_h; fullscreen_mode.refresh_rate = state->refresh_rate; SDL_SetFullscreenDisplayMode(&fullscreen_mode); state->windows = (SDL_WindowID *) SDL_malloc(state->num_windows * sizeof(*state->windows)); if (!state->windows) { fprintf(stderr, "Out of memory!\n"); return SDL_FALSE; } for (i = 0; i < state->num_windows; ++i) { char title[1024]; if (state->num_windows > 1) { SDL_snprintf(title, SDL_arraysize(title), "%s %d", state->window_title, i + 1); } else { SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); } state->windows[i] = SDL_CreateWindow(title, state->window_x, state->window_y, state->window_w, state->window_h, state->window_flags); if (!state->windows[i]) { fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); return SDL_FALSE; } if (!state->skip_renderer && (state->renderdriver || !(state->window_flags & SDL_WINDOW_OPENGL))) { m = -1; if (state->renderdriver) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); for (j = 0; j < n; ++j) { SDL_GetRenderDriverInfo(j, &info); if (SDL_strcasecmp(info.name, state->renderdriver) == 0) { m = j; break; } } if (m == n) { fprintf(stderr, "Couldn't find render driver named %s", state->renderdriver); return SDL_FALSE; } } if (SDL_CreateRenderer (state->windows[i], m, state->render_flags) < 0) { fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; fprintf(stderr, "Current renderer:\n"); SDL_GetRendererInfo(&info); PrintRenderer(&info); } } } SDL_SelectRenderer(state->windows[0]); } if (state->flags & SDL_INIT_AUDIO) { if (state->verbose & VERBOSE_AUDIO) { n = SDL_GetNumAudioDrivers(); if (n == 0) { fprintf(stderr, "No built-in audio drivers\n"); } else { fprintf(stderr, "Built-in audio drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetAudioDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_AudioInit(state->audiodriver) < 0) { fprintf(stderr, "Couldn't initialize audio driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Audio driver: %s\n", SDL_GetCurrentAudioDriver()); } if (SDL_OpenAudio(&state->audiospec, NULL) < 0) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return SDL_FALSE; } } return SDL_TRUE; }
int Window::getDisplayCount() const { return SDL_GetNumVideoDisplays(); }
SDLWindowManager::SDLWindowManager(Application* application): WindowManager(application) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == -1) { throw RuntimeException("SDL initialization failed."); } int displayCount = SDL_GetNumVideoDisplays(); displays.resize(displayCount); primaryDisplay = &displays[0]; for (int i = 0; i < displayCount; ++i) { Display* display = &displays[i]; const char* displayName = SDL_GetDisplayName(i); if (displayName) { display->setName(displayName); } SDL_DisplayMode sdlCurrentDisplayMode; SDL_GetCurrentDisplayMode(i, &sdlCurrentDisplayMode); int displayModeCount = SDL_GetNumDisplayModes(i); for (int j = 0; j < displayModeCount; ++j) { SDL_DisplayMode sdlDisplayMode; SDL_GetDisplayMode(i, j, &sdlDisplayMode); SDL_PixelFormat* format = SDL_AllocFormat(sdlDisplayMode.format); if (!format) { std::cerr << "Failed to create SDL pixel format: " << SDL_GetPixelFormatName(sdlDisplayMode.format) << '\n'; continue; } int width = sdlDisplayMode.w; int height = sdlDisplayMode.h; int refreshRate = sdlDisplayMode.refresh_rate; int redBits, greenBits, blueBits, alphaBits; SDLPixelFormatMap::getChannelBits(format, &redBits, &greenBits, &blueBits, &alphaBits); SDL_FreeFormat(format); display->addMode( DisplayMode(width, height, redBits, greenBits, blueBits, alphaBits, refreshRate)); if (sdlCurrentDisplayMode.w == sdlDisplayMode.w && sdlCurrentDisplayMode.h == sdlDisplayMode.h && sdlCurrentDisplayMode.format == sdlDisplayMode.format && sdlCurrentDisplayMode.refresh_rate == sdlDisplayMode.refresh_rate) { display->setCurrentMode(j); } } } keyboard = new Keyboard("Default Keyboard"); mouse = new Mouse("Default Mouse"); application->getInputManager()->registerKeyboard(keyboard); application->getInputManager()->registerMouse(mouse); }
static void fs_emu_monitor_init() { static bool initialized = false; if (initialized) { return; } initialized = true; g_fs_emu_monitors = g_array_new(false, true, sizeof(FSEmuMonitor)); int display_index = 0; SDL_DisplayMode mode; int error = SDL_GetCurrentDisplayMode(display_index, &mode); if (error) { fs_log("SDL_GetCurrentDisplayMode failed\n"); SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Display Error", "SDL_GetCurrentDisplayMode failed.", NULL); exit(1); } g_fs_emu_monitor_count = SDL_GetNumVideoDisplays(); if (g_fs_emu_monitor_count < 1) { fs_log("Error %d retrieving number of displays/monitors\n", g_fs_emu_monitor_count); g_fs_emu_monitor_count = 1; } if (g_fs_emu_monitor_count > FS_EMU_MONITOR_MAX_COUNT) { fs_log("Limiting number of displays to %d\n", FS_EMU_MONITOR_MAX_COUNT); g_fs_emu_monitor_count = FS_EMU_MONITOR_MAX_COUNT; } for (int i = 0; i < g_fs_emu_monitor_count; i++) { SDL_Rect rect; FSEmuMonitor monitor; int error = SDL_GetDisplayBounds(i, &rect); if (error) { fs_log("Error retrieving display bounds for display %d: %s\n", i, SDL_GetError()); /* Setting dummy values on error*/ rect.x = 0; rect.y = 0; rect.w = 1024; rect.h = 768; } monitor.rect.x = rect.x; monitor.rect.y = rect.y; monitor.rect.w = rect.w; monitor.rect.h = rect.h; monitor.index = i; g_array_append_val(g_fs_emu_monitors, monitor); } g_array_sort(g_fs_emu_monitors, fs_emu_monitor_compare); for (int i = 0; i < g_fs_emu_monitor_count; i++) { g_array_index(g_fs_emu_monitors, FSEmuMonitor, i).index = i; /* Set physical position flags (left, m-left, m-right, right) */ int flags = 0; for (int j = 0; j < 4; j++) { int pos = (g_fs_emu_monitor_count - 1.0) * j / 3.0 + 0.5; fs_log("Monitor - j %d pos %d\n", j, pos); if (pos == i) { flags |= (1 << j); } } fs_log("Monitor index %d flags %d\n", i, flags); g_array_index(g_fs_emu_monitors, FSEmuMonitor, i).flags = flags; } }