SDL_Surface *TCOD_sys_read_png(const char *filename) { unsigned error; unsigned char* image; unsigned width, height, y, bpp; unsigned char* png; size_t pngsize; LodePNGState state; SDL_Surface *bitmap; unsigned char *source; unsigned int rowsize; lodepng_state_init(&state); /*optionally customize the state*/ if (!TCOD_sys_read_file(filename,&png,&pngsize)) return NULL; lodepng_inspect(&width,&height,&state, png, pngsize); bpp=lodepng_get_bpp(&state.info_png.color); if ( bpp == 24 ) { /* don't convert to 32 bits because libtcod's 24bits renderer is faster */ state.info_raw.colortype=LCT_RGB; } else if ( bpp != 24 && bpp != 32 ) { /* paletted png. convert to 24 bits */ state.info_raw.colortype=LCT_RGB; state.info_raw.bitdepth=8; bpp=24; } error = lodepng_decode(&image, &width, &height, &state, png, pngsize); free(png); if(error) { printf("error %u: %s\n", error, lodepng_error_text(error)); lodepng_state_cleanup(&state); return NULL; } /* create the SDL surface */ bitmap=TCOD_sys_get_surface(width,height,bpp==32); source=image; rowsize=width*bpp/8; for (y=0; y< height; y++ ) { Uint8 *row_pointer=(Uint8 *)(bitmap->pixels) + y * bitmap->pitch; memcpy(row_pointer,source,rowsize); source+=rowsize; } lodepng_state_cleanup(&state); free(image); return bitmap; }
void *TCOD_sys_create_bitmap_for_console(TCOD_console_t console) { int w,h; w = TCOD_console_get_width(console) * fontWidth; h = TCOD_console_get_height(console) * fontHeight; return TCOD_sys_get_surface(w,h,false); }
SDL_Surface *TCOD_sys_read_png(const char *filename) { png_uint_32 png_width,png_height,y; int png_bit_depth,png_color_type,png_interlace_type; png_structp png_ptr; png_infop info_ptr; FILE *fp; SDL_Surface *bitmap; png_bytep *row_pointers; if ((fp = fopen(filename, "rb")) == NULL) return NULL; /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also supply the * the compiler header file version, so that we know if the application * was compiled with a compatible version of the library. REQUIRED */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL); if (png_ptr == NULL) { fclose(fp); return NULL; } /* Allocate/initialize the memory for image information. REQUIRED. */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fclose(fp); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); return NULL; } /* Set error handling if you are using the setjmp/longjmp method (this is * the normal method of doing things with libpng). REQUIRED unless you * set up your own error handlers in the png_create_read_struct() earlier. */ if (setjmp(png_jmpbuf(png_ptr))) { /* Free all of the memory associated with the png_ptr and info_ptr */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); fclose(fp); /* If we get here, we had a problem reading the file */ return NULL; } png_init_io(png_ptr, fp); /* * If you have enough memory to read in the entire image at once, * and you need to specify only transforms that can be controlled * with one of the PNG_TRANSFORM_* bits (this presently excludes * dithering, filling, setting background, and doing gamma * adjustment), then you can read the entire image (including * pixels) into the info structure with this call: */ /*png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, png_voidp_NULL); */ /* get info about the image */ png_read_info(png_ptr,info_ptr); png_get_IHDR(png_ptr,info_ptr,&png_width,&png_height,&png_bit_depth,&png_color_type, &png_interlace_type,NULL,NULL); /* convert the image to a format suitable with libtcod */ png_set_strip_16(png_ptr); /* 16 bits channels => 8 bits channels */ png_set_packing(png_ptr); /* 1,2,4 bits depth => 24/32 bits depth */ if ( png_color_type == PNG_COLOR_TYPE_GRAY ) png_set_expand(png_ptr); /* grayscale => color */ if ( png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) png_set_gray_to_rgb(png_ptr); /* update the image information */ png_read_update_info(png_ptr,info_ptr); png_get_IHDR(png_ptr,info_ptr,&png_width,&png_height,&png_bit_depth,&png_color_type, &png_interlace_type,NULL,NULL); /* create the SDL surface */ bitmap=TCOD_sys_get_surface(png_width,png_height,info_ptr->channels == 4); /* get row data */ row_pointers=(png_bytep *)malloc(sizeof(png_bytep)*png_height); for (y=0; y< png_height; y++ ) { row_pointers[y]=(png_bytep)(Uint8 *)(bitmap->pixels) + y * bitmap->pitch; } /* read png data directly into the SDL surface */ png_read_image(png_ptr,row_pointers); /* clean up after the read, and free any memory allocated - REQUIRED */ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); free(row_pointers); /* close the file */ fclose(fp); return bitmap; }
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; } }