static void create_window(int w, int h, bool fullscreen) { Uint32 winflags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; #if defined(TCOD_ANDROID) /* Android should always be fullscreen. */ TCOD_ctx.fullscreen = fullscreen = true; #endif if ( fullscreen ) { find_resolution(); #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); winflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS | SDL_WINDOW_OPENGL; # if defined(TCOD_ANDROID) && defined(FUTURE_SUPPORT) winflags |= SDL_WINDOW_RESIZABLE; # endif window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,winflags); if ( window && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { winflags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; # if defined(TCOD_ANDROID) && defined(FUTURE_SUPPORT) winflags |= SDL_WINDOW_RESIZABLE; # endif window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,winflags); if ( window == NULL ) TCOD_fatal_nopar("SDL : cannot set fullscreen video mode"); } SDL_ShowCursor(0); SDL_GetWindowSize(window,&TCOD_ctx.actual_fullscreen_width,&TCOD_ctx.actual_fullscreen_height); TCOD_sys_init_screen_offset(); } else { #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); winflags |= SDL_WINDOW_OPENGL; window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,winflags); if ( window && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { window = SDL_CreateWindow(TCOD_ctx.window_title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,winflags); TCOD_LOG(("Using SDL renderer...\n")); } if ( window == NULL ) TCOD_fatal_nopar("SDL : cannot create window"); } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if ( renderer == NULL ) TCOD_fatal_nopar("SDL : cannot create renderer"); SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); }
static void create_window(int w, int h, bool fullscreen) { if ( fullscreen ) { find_resolution(); #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); screen=SDL_SetVideoMode(TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,32,SDL_FULLSCREEN|SDL_OPENGL); if ( screen && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { screen=SDL_SetVideoMode(TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,32,SDL_FULLSCREEN); if ( screen == NULL ) TCOD_fatal_nopar("SDL : cannot set fullscreen video mode"); } SDL_ShowCursor(0); TCOD_ctx.actual_fullscreen_width=screen->w; TCOD_ctx.actual_fullscreen_height=screen->h; TCOD_sys_init_screen_offset(); SDL_FillRect(screen,0,0); } else { #ifndef NO_OPENGL if (TCOD_ctx.renderer != TCOD_RENDERER_SDL ) { TCOD_opengl_init_attributes(); screen=SDL_SetVideoMode(w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,32,SDL_OPENGL); if ( screen && TCOD_opengl_init_state(w, h, charmap) && TCOD_opengl_init_shaders() ) { TCOD_LOG(("Using %s renderer...\n",TCOD_ctx.renderer == TCOD_RENDERER_GLSL ? "GLSL" : "OPENGL")); } else { TCOD_LOG(("Fallback to SDL renderer...\n")); TCOD_ctx.renderer = TCOD_RENDERER_SDL; } } #endif if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { screen=SDL_SetVideoMode(w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,32,0); TCOD_LOG(("Using SDL renderer...\n")); } if ( screen == NULL ) TCOD_fatal_nopar("SDL : cannot create window"); } SDL_EnableUNICODE(1); TCOD_ctx.fullscreen=fullscreen; }
static void save_screenshot(const char *filename) { if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { /* This would be a lot easier if image saving could do textures. */ SDL_Rect rect; SDL_RenderGetViewport(renderer, &rect); Uint32 format = SDL_GetWindowPixelFormat(window); SDL_Texture *texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_TARGET, rect.w, rect.h); if (0 != texture) { if (SDL_SetRenderTarget(renderer, texture)) { void *pixels; int pitch, access; actual_rendering(); SDL_SetRenderTarget(renderer, NULL); rect.x = rect.y = rect.w = rect.h = 0; if (-1 != SDL_QueryTexture(texture, &format, &access, &rect.w, &rect.h) && -1 != SDL_LockTexture(texture, NULL, &pixels, &pitch)) { int depth; Uint32 rmask, gmask, bmask, amask; if (SDL_TRUE == SDL_PixelFormatEnumToMasks(format, &depth, &rmask, &gmask, &bmask, &amask)) { SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(pixels, rect.w, rect.h, depth, pitch, rmask, gmask, bmask, amask); TCOD_sys_save_bitmap((void *)surface,filename); SDL_FreeSurface(surface); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_PixelFormatEnumToMasks")); SDL_UnlockTexture(texture); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_QueryTexture or SDL_LockTexture")); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_SetRenderTarget")); SDL_DestroyTexture(texture); } else TCOD_LOG(("TCOD_sys_save_screenshot - failed call to SDL_CreateTexture")); #ifndef NO_OPENGL } else { SDL_Surface *screenshot=(SDL_Surface *)TCOD_opengl_get_screen(); TCOD_sys_save_bitmap((void *)screenshot,filename); SDL_FreeSurface(screenshot); #endif } }
bool TCOD_sys_init(int w,int h, char_t *buf, char_t *oldbuf, bool fullscreen) { FILE *f; if ( ! has_startup ) TCOD_sys_startup(); /* check if there is a user (player) config file */ f = fopen("./libtcod.cfg","r"); if ( f ) { fclose(f); /* yes, read it */ TCOD_sys_load_player_config(); if (TCOD_ctx.fullscreen) fullscreen=true; } if (! charmap) TCOD_sys_load_font(); if ( fullscreen ) { find_resolution(); if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { screen=SDL_SetVideoMode(TCOD_ctx.actual_fullscreen_width,TCOD_ctx.actual_fullscreen_height,32,SDL_FULLSCREEN); if ( screen == NULL ) TCOD_fatal_nopar("SDL : cannot set fullscreen video mode"); } SDL_ShowCursor(0); TCOD_ctx.actual_fullscreen_width=screen->w; TCOD_ctx.actual_fullscreen_height=screen->h; TCOD_ctx.fullscreen_offsetx=(TCOD_ctx.actual_fullscreen_width-TCOD_ctx.root->w*TCOD_ctx.font_width)/2; TCOD_ctx.fullscreen_offsety=(TCOD_ctx.actual_fullscreen_height-TCOD_ctx.root->h*TCOD_ctx.font_height)/2; SDL_FillRect(screen,0,0); } else { if (TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { screen=SDL_SetVideoMode(w*TCOD_ctx.font_width,h*TCOD_ctx.font_height,32,0); TCOD_LOG(("Using SDL renderer...\n")); } if ( screen == NULL ) TCOD_fatal_nopar("SDL : cannot create window"); } SDL_EnableUNICODE(1); consoleBuffer=buf; prevConsoleBuffer=oldbuf; TCOD_ctx.fullscreen=fullscreen; memset(key_status,0,sizeof(bool)*(TCODK_CHAR+1)); memset(ascii_updated,0,sizeof(bool)*TCOD_ctx.max_font_chars); return true; }
/* call after creating window */ bool TCOD_opengl_init_state(int conw, int conh, void *font) { SDL_Surface *font_surf=(SDL_Surface *)font; /* convert font for opengl */ Uint32 rmask, gmask, bmask, amask; SDL_Surface *temp; SDL_Surface *temp_alpha; /* check opengl extensions */ if ( TCOD_ctx.renderer == TCOD_RENDERER_GLSL ) { bool hasShader = false; const char *glexts=(const char *)glGetString(GL_EXTENSIONS); if (glexts ) { hasShader = (strstr(glexts,"GL_ARB_shader_objects") != NULL); } if (! hasShader ) { TCOD_LOG(("Missing GL_ARB_shader_objects extension. Falling back to fixed pipeline...\n")); TCOD_ctx.renderer = TCOD_RENDERER_OPENGL; } } /* set extensions functions pointers */ glCreateShaderObjectARB=(PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB"); glGetObjectParameterivARB=(PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB"); glShaderSourceARB=(PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB"); glCompileShaderARB=(PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB"); glGetInfoLogARB=(PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB"); glCreateProgramObjectARB=(PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB"); glAttachObjectARB=(PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB"); glLinkProgramARB=(PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB"); glUseProgramObjectARB=(PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB"); glUniform2fARB=(PFNGLUNIFORM2FARBPROC)SDL_GL_GetProcAddress("glUniform2fARB"); glGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB"); glUniform1fARB=(PFNGLUNIFORM1FARBPROC)SDL_GL_GetProcAddress("glUniform1fARB"); glUniform1iARB=(PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB"); #ifdef TCOD_WINDOWS glActiveTexture=(PFNGLACTIVETEXTUREPROC)SDL_GL_GetProcAddress("glActiveTexture"); #endif /* set opengl state */ glEnable(GL_TEXTURE_2D); glClearColor(1.0f, 1.0f, 0.0f, 0.0f); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glClear( GL_COLOR_BUFFER_BIT ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if ( TCOD_ctx.renderer == TCOD_RENDERER_GLSL ) { glOrtho(0, conw, 0, conh, -1.0f, 1.0f); glDisable (GL_BLEND); } else { glOrtho(0, conw, conh, 0.0f, -1.0f, 1.0f); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); /*#ifdef TCOD_WINDOWS */ if ( ! TCOD_ctx.fullscreen ) { /* turn vsync off in windowed mode */ typedef bool (APIENTRY *PFNWGLSWAPINTERVALFARPROC)(int); PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0; wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)SDL_GL_GetProcAddress("wglSwapIntervalEXT"); if (wglSwapIntervalEXT) wglSwapIntervalEXT(0); } /*#endif */ /* compute pot size */ conwidth=conw; conheight=conh; POTconwidth=POTconheight=1; while ( POTconwidth < conw ) POTconwidth *= 2; while ( POTconheight < conh ) POTconheight *= 2; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif fontwidth=font_surf->w; fontheight=font_surf->h; POTfontwidth=POTfontheight=1; while ( POTfontwidth < fontwidth ) POTfontwidth *= 2; while ( POTfontheight < fontheight ) POTfontheight *= 2; SDL_SetColorKey(font_surf, SDL_SRCCOLORKEY, SDL_MapRGB(font_surf->format, 0, 0, 0)); temp_alpha = SDL_DisplayFormatAlpha(font_surf); SDL_SetAlpha(temp_alpha, 0, SDL_ALPHA_TRANSPARENT); temp = SDL_CreateRGBSurface(SDL_SWSURFACE, POTfontwidth, POTfontheight, 32, bmask, gmask, rmask, amask); /*BGRA */ SDL_BlitSurface(temp_alpha, NULL, temp, NULL); SDL_FreeSurface(temp_alpha); CHECKGL(glGenTextures(1, &font_tex)); CHECKGL(glBindTexture(GL_TEXTURE_2D, font_tex)); SDL_LockSurface(temp); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); CHECKGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, temp->w, temp->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp->pixels)); SDL_UnlockSurface(temp); SDL_FreeSurface(temp); return true; }