bool TCOD_sys_init(int w,int h, char_t *buf, char_t *oldbuf, bool fullscreen) { consoleWidth=w; consoleHeight=h; if ( fullscreen ) { find_resolution(); sfWindowSettings Settings = {0, 0, 0}; sfVideoMode Mode = {actual_fullscreen_width, actual_fullscreen_height, 32}; renderWindow=sfRenderWindow_Create(Mode,window_title,sfFullscreen,Settings); TCOD_mouse_show_cursor(false); actual_fullscreen_width=sfRenderWindow_GetWidth(renderWindow); actual_fullscreen_height=sfRenderWindow_GetHeight(renderWindow); fullscreen_offsetx=(actual_fullscreen_width-consoleWidth*fontWidth)/2; fullscreen_offsety=(actual_fullscreen_height-consoleHeight*fontHeight)/2; } else { sfWindowSettings Settings = {0, 0, 0}; sfVideoMode Mode = {w*fontWidth, h*fontHeight, 32}; renderWindow=sfRenderWindow_Create(Mode,window_title,sfClose,Settings); TCOD_mouse_show_cursor(true); } charmap=sfImage_CreateFromFile(font_file); if (charmap == NULL ) TCOD_fatal("SFML : cannot load %s",font_file); if ( sfImage_GetWidth(charmap) < fontNbCharHoriz * fontWidth || sfImage_GetHeight(charmap) < fontNbCharVertic * fontHeight ) TCOD_fatal("bitmap %s too small for %dx%d, %dx%d characters\n", font_file,fontWidth,fontHeight,fontNbCharHoriz,fontNbCharVertic); sfColor colorKey={fontKeyCol.r,fontKeyCol.g,fontKeyCol.b,255}; sfImage_CreateMaskFromColor(charmap, colorKey, 0); sfImage_SetSmooth(charmap, sfFalse); sfImage_Bind(charmap); charmapSprite=sfSprite_Create(); sfSprite_SetImage(charmapSprite,charmap); sfSprite_SetBlendMode(charmapSprite,sfBlendNone); consoleBuffer=buf; prevConsoleBuffer=oldbuf; fullscreen_on=fullscreen; memset(key_status,0,sizeof(bool)*(TCODK_CHAR+1)); return true; }
static TCOD_path_data_t *TCOD_path_new_intern(int w, int h) { TCOD_path_data_t *path=(TCOD_path_data_t *)calloc(sizeof(TCOD_path_data_t),1); path->w=w; path->h=h; path->grid=(float *)calloc(sizeof(float),w*h); path->heur=(float *)calloc(sizeof(float),w*h); path->prev=(dir_t *)calloc(sizeof(dir_t),w*h); if (! path->grid || ! path->heur || ! path->prev ) { TCOD_fatal("Fatal error : path finding module cannot allocate djikstra grids (size %dx%d)\n",w,h); exit(1); } path->path=TCOD_list_new(); path->heap=TCOD_list_new(); return path; }
void TCOD_map_compute_fov_permissive2(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls, int fovType) { int c,minx,maxx,miny,maxy; map_t *m = (map_t *)map; if ( (unsigned)fovType>8 ) TCOD_fatal("Bad permissiveness %d for FOV_PERMISSIVE. Accepted range is [0,8].\n",fovType); offset=8-fovType; limit=8+fovType; // clean the map for (c=m->nbcells-1; c >= 0; c--) { m->cells[c].fov=0; } m->cells[player_x+player_y*m->width].fov=1; // preallocate views and bumps views=(view_t *)calloc(sizeof(view_t),m->width*m->height); bumps=(viewbump_t *)calloc(sizeof(viewbump_t),m->width*m->height); // set the fov range if ( max_radius > 0 ) { minx=MIN(player_x,max_radius); maxx=MIN(m->width-player_x-1,max_radius); miny=MIN(player_y,max_radius); maxy=MIN(m->height-player_y-1,max_radius); } else { minx=player_x; maxx=m->width-player_x-1; miny=player_y; maxy=m->height-player_y-1; } // calculate fov. precise permissive field of view bumpidx=0; check_quadrant(m,player_x,player_y,1,1,maxx,maxy, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,1,-1,maxx,miny, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,-1,-1,minx,miny, light_walls); bumpidx=0; check_quadrant(m,player_x,player_y,-1,1,minx,maxy, light_walls); free(bumps); free(views); }
SDL_Surface *TCOD_sys_read_bmp(const char *filename) { SDL_Surface *ret=SDL_LoadBMP(filename); if( !ret ) TCOD_fatal("SDL : %s",SDL_GetError()); /* convert low color images to 24 bits */ if ( ret->format->BytesPerPixel != 3 ) { Uint32 rmask,gmask,bmask; SDL_Surface * tmp; if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { rmask=0xFF0000; gmask=0x00FF00; bmask=0x0000FF; } else { rmask=0x0000FF; gmask=0x00FF00; bmask=0xFF0000; } tmp=SDL_CreateRGBSurface(SDL_SWSURFACE,ret->w,ret->h,24, rmask, gmask, bmask, 0); SDL_BlitSurface(ret,NULL,tmp,NULL); SDL_FreeSurface(ret); ret=tmp; } return ret; }
void TCOD_sys_load_font() { int i; bool hasTransparent=false; int x,y; charmap=TCOD_sys_load_image(font_file); if (charmap == NULL ) TCOD_fatal("SDL : cannot load %s",font_file); if ( (float)(charmap->w / fontNbCharHoriz) != charmap->w / fontNbCharHoriz || (float)(charmap->h / fontNbCharVertic) != charmap->h / fontNbCharVertic ) TCOD_fatal(" %s size is not a multiple of font layout (%dx%d)\n", font_file,fontNbCharHoriz,fontNbCharVertic); fontWidth=charmap->w/fontNbCharHoriz; fontHeight=charmap->h/fontNbCharVertic; check_ascii_to_tcod(); // figure out what kind of font we have // check if the alpha layer is actually used if ( charmap->format->BytesPerPixel == 4 ) for (x=0; !hasTransparent && x < charmap->w; x ++ ) { for (y=0;!hasTransparent && y < charmap->h; y++ ) { Uint8 *pixel=(Uint8 *)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel; Uint8 alpha=*((pixel)+charmap->format->Ashift/8); if ( alpha < 255 ) { hasTransparent=true; } } } if (! hasTransparent ) { // 24 bit font. check if greyscale int x,y,keyx,keyy; Uint8 *pixel; // the key color is found on the character corresponding to space ' ' if ( fontTcodLayout ) { keyx = fontWidth/2; keyy = fontHeight/2; } else if (fontInRow) { keyx = ((int)(' ') % fontNbCharHoriz ) * fontWidth + fontWidth/2; keyy = ((int)(' ') / fontNbCharHoriz ) * fontHeight + fontHeight/2; } else { keyx = ((int)(' ') / fontNbCharVertic ) * fontWidth + fontWidth/2; keyy = ((int)(' ') % fontNbCharVertic ) * fontHeight + fontHeight/2; } pixel=(Uint8 *)(charmap->pixels) + keyy * charmap->pitch + keyx * charmap->format->BytesPerPixel; fontKeyCol.r=*((pixel)+charmap->format->Rshift/8); fontKeyCol.g=*((pixel)+charmap->format->Gshift/8); fontKeyCol.b=*((pixel)+charmap->format->Bshift/8); // convert greyscale to font with alpha layer if ( fontIsGreyscale ) { bool invert=( fontKeyCol.r > 128 ); // black on white font ? // convert it to 32 bits if needed if ( charmap->format->BytesPerPixel != 4 ) { SDL_Surface *temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,true); SDL_BlitSurface(charmap,NULL,temp,NULL); SDL_FreeSurface(charmap); charmap=temp; } for (x=0; x < charmap->w; x ++ ) { for (y=0;y < charmap->h; y++ ) { Uint8 *pixel=(Uint8 *)(charmap->pixels) + y * charmap->pitch + x * charmap->format->BytesPerPixel; Uint8 r=*((pixel)+charmap->format->Rshift/8); *((pixel)+charmap->format->Ashift/8) = (invert ? 255-r : r); *((pixel)+charmap->format->Rshift/8)=255; *((pixel)+charmap->format->Gshift/8)=255; *((pixel)+charmap->format->Bshift/8)=255; } } } else { // alpha layer not used. convert to 24 bits (faster) SDL_Surface *temp=(SDL_Surface *)TCOD_sys_get_surface(charmap->w,charmap->h,false); SDL_BlitSurface(charmap,NULL,temp,NULL); SDL_FreeSurface(charmap); charmap=temp; } } /* charmap=SDL_CreateRGBSurface(SDL_SWSURFACE,charmap->w,charmap->h,24,0xFF0000, 0xFF00, 0xFF, 0); if ( SDL_MUSTLOCK( charmap ) ) SDL_LockSurface( charmap ); SDL_BlitSurface(charmap,NULL,charmap,NULL); */ sdl_key=SDL_MapRGB(charmap->format,fontKeyCol.r,fontKeyCol.g,fontKeyCol.b); rgb_mask=charmap->format->Rmask|charmap->format->Gmask|charmap->format->Bmask; nrgb_mask = ~ rgb_mask; sdl_key &= rgb_mask; // remove the alpha part if ( charmap->format->BytesPerPixel == 3 ) SDL_SetColorKey(charmap,SDL_SRCCOLORKEY|SDL_RLEACCEL,sdl_key); for (i=0; i < fontNbCharHoriz*fontNbCharVertic; i++ ) { charcols[i]=fontKeyCol; first_draw[i]=true; } check_ascii_to_tcod(); if (!fontTcodLayout) { // apply standard ascii mapping for (i=0; i < TCOD_max_font_chars; i++ ) ascii_to_tcod[i]=i; } }
/* In order to avoid rendering race conditions and the ensuing segmentation * faults, this should only be called when it would normally be and not * specifically to force screen refreshes. To this end, and to avoid * threading complications it takes care of special cases internally. */ static void render(void *vbitmap, int console_width, int console_height, char_t *console_buffer, char_t *prev_console_buffer) { char_t *prev_console_buffer_ptr = prev_console_buffer; if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { int console_width_p = console_width*TCOD_ctx.font_width; int console_height_p = console_height*TCOD_ctx.font_height; /* Make a bitmap of exact rendering size and correct format. */ if (scale_screen == NULL) { int bpp; Uint32 rmask, gmask, bmask, amask; if (SDL_PixelFormatEnumToMasks(SDL_GetWindowPixelFormat(window), &bpp, &rmask, &gmask, &bmask, &amask) == SDL_FALSE) { TCOD_fatal("SDL : failed to create scaling surface : indeterminate window pixel format"); return; } scale_screen=SDL_CreateRGBSurface(SDL_SWSURFACE,console_width_p,console_height_p,bpp,rmask,gmask,bmask,amask); if (scale_screen == NULL) { TCOD_fatal("SDL : failed to create scaling surface"); return; } } else if (clear_screen) { clear_screen=false; SDL_FillRect(scale_screen,0,0); /* Implicitly do complete console redraw, not just tracked changes. */ prev_console_buffer_ptr = NULL; } TCOD_sys_console_to_bitmap(scale_screen, console_width, console_height, console_buffer, prev_console_buffer_ptr); /* Scale the rendered bitmap to the screen, preserving aspect ratio, and blit it. * This data is also used for console coordinate resolution.. */ if (scale_data.last_scale_factor != scale_factor || scale_data.last_scale_xc != scale_xc || scale_data.last_scale_yc != scale_yc || scale_data.last_fullscreen != TCOD_ctx.fullscreen || scale_data.force_recalc) { /* Preserve old value of input variables, to enable recalculation if they change. */ scale_data.last_scale_factor = scale_factor; scale_data.last_scale_xc = scale_xc; scale_data.last_scale_yc = scale_yc; scale_data.last_fullscreen = TCOD_ctx.fullscreen; scale_data.force_recalc = 0; if (scale_data.last_fullscreen) { scale_data.surface_width = TCOD_ctx.actual_fullscreen_width; scale_data.surface_height = TCOD_ctx.actual_fullscreen_height; } else { scale_data.surface_width = console_width_p; scale_data.surface_height = console_height_p; } scale_data.min_scale_factor = MAX((float)console_width_p/scale_data.surface_width, (float)console_height_p/scale_data.surface_height); if (scale_data.min_scale_factor > 1.0f) scale_data.min_scale_factor = 1.0f; /*printf("min_scale_factor %0.3f = MAX(%d/%d, %d/%d)", scale_data.min_scale_factor, console_width_p, scale_data.surface_width, console_height_p, scale_data.surface_height);*/ scale_data.dst_height_width_ratio = (float)scale_data.surface_height/scale_data.surface_width; scale_data.src_proportionate_width = (int)(console_width_p / scale_factor); scale_data.src_proportionate_height = (int)((console_width_p * scale_data.dst_height_width_ratio) / scale_factor); /* Work out how much of the console to copy. */ scale_data.src_x0 = (scale_xc * console_width_p) - (0.5f * scale_data.src_proportionate_width); if (scale_data.src_x0 + scale_data.src_proportionate_width > console_width_p) scale_data.src_x0 = console_width_p - scale_data.src_proportionate_width; if (scale_data.src_x0 < 0) scale_data.src_x0 = 0; scale_data.src_copy_width = scale_data.src_proportionate_width; if (scale_data.src_x0 + scale_data.src_copy_width > console_width_p) scale_data.src_copy_width = console_width_p - scale_data.src_x0; scale_data.src_y0 = (scale_yc * console_height_p) - (0.5f * scale_data.src_proportionate_height); if (scale_data.src_y0 + scale_data.src_proportionate_height > console_height_p) scale_data.src_y0 = console_height_p - scale_data.src_proportionate_height; if (scale_data.src_y0 < 0) scale_data.src_y0 = 0; scale_data.src_copy_height = scale_data.src_proportionate_height; if (scale_data.src_y0 + scale_data.src_copy_height > console_height_p) scale_data.src_copy_height = console_height_p - scale_data.src_y0; scale_data.dst_display_width = (scale_data.src_copy_width * scale_data.surface_width) / scale_data.src_proportionate_width; scale_data.dst_display_height = (scale_data.src_copy_height * scale_data.surface_height) / scale_data.src_proportionate_height; scale_data.dst_offset_x = (scale_data.surface_width - scale_data.dst_display_width)/2; scale_data.dst_offset_y = (scale_data.surface_height - scale_data.dst_display_height)/2; } SDL_RenderClear(renderer); actual_rendering(); SDL_RenderPresent(renderer); } #ifndef NO_OPENGL else { TCOD_opengl_render(oldFade, ascii_updated, console_buffer, prev_console_buffer); TCOD_opengl_swap(); } #endif oldFade=(int)TCOD_console_get_fade(); if ( any_ascii_updated ) { memset(ascii_updated,0,sizeof(bool)*TCOD_ctx.max_font_chars); any_ascii_updated=false; } }