예제 #1
0
/* Loads PNG using libpng */
static TLN_Bitmap LoadPNG (char *filename)
{
    png_image image;
    TLN_Bitmap bitmap = NULL;

    /* Only the image structure version number needs to be set. */
    memset (&image, 0, sizeof image);
    image.version = PNG_IMAGE_VERSION;

    if (png_image_begin_read_from_file (&image, filename))
    {
        int src_line_size = image.width * PNG_IMAGE_PIXEL_SIZE(image.format);
        int lut_size = PNG_IMAGE_COLORMAP_SIZE(image);
        BYTE* data = malloc (src_line_size * image.height);
        BYTE* lut = malloc (lut_size);

        bitmap = TLN_CreateBitmap (image.width, image.height, PNG_IMAGE_PIXEL_SIZE(image.format)<<3);

        /* Change this to try different formats!  If you set a colormap format
        * then you must also supply a colormap below.
        */
        image.format = PNG_FORMAT_RGB_COLORMAP;
        if (png_image_finish_read (&image, NULL, data, 0, lut))
        {
            BYTE *src, *dst;
            unsigned int c;

            png_image_free (&image);

            /* copy scanlines */
            src = data;
            for (c=0; c<image.height; c++)
            {
                dst = TLN_GetBitmapPtr (bitmap, 0, c);
                memcpy (dst, src, src_line_size);
                src += src_line_size;
            }

            /* get palette */
            {
                BYTE *src = lut;
                png_uint_32 c;
                TLN_Palette palette;
                palette = TLN_CreatePalette (image.colormap_entries);
                for (c=0; c<image.colormap_entries; c++)
                {
                    TLN_SetPaletteColor (palette, c, src[0], src[1], src[2]);
                    src += 3;
                }
                TLN_SetBitmapPalette (bitmap, palette);
            }
        }
        free (lut);
        free (data);
    }
    return bitmap;
}
예제 #2
0
/*!
 * \brief
 * Loads a tileset from a Tiled .tsx file
 *
 * \param filename
 * TSX file to load
 *
 * \returns
 * Reference to the newly loaded tileset or NULL if error
 *
 * \remarks
 * An associated palette is also created, it can be obtained calling TLN_GetTilesetPalette()
 */
TLN_Tileset TLN_LoadTileset (char *filename)
{
    SimpleXmlParser parser;
    size_t size;
    BYTE *data;
    TLN_Tileset tileset;
    TLN_Bitmap bitmap;
    int htiles, vtiles;
    int x,y,dx,dy;
    int id;
    int pitch;

    /* load file */
    data = LoadFile (filename, &size);
    if (!data)
        return NULL;

    /* parse */
    memset (&loader, 0, sizeof(loader));
    parser = simpleXmlCreateParser (data, (long)size);
    if (parser != NULL)
    {
        if (simpleXmlParse(parser, handler) != 0)
        {
            printf("parse error on line %li:\n%s\n",
                   simpleXmlGetLineNumber(parser), simpleXmlGetErrorDescription(parser));
            free (data);
            return NULL;
        }
    }
    free (data);

    /* check filename */
    if (!loader.source[0])
        return NULL;

    /* load picture */
    bitmap = TLN_LoadBitmap (loader.source);
    if (!bitmap)
        return NULL;

    /* create tileset */
    dx = loader.tilewidth + loader.spacing;
    dy = loader.tileheight + loader.spacing;
    htiles = (TLN_GetBitmapWidth(bitmap) - loader.margin*2 + loader.spacing) / dx;
    vtiles = (TLN_GetBitmapHeight(bitmap) - loader.margin*2 + loader.spacing) / dy;
    tileset = TLN_CreateTileset (htiles*vtiles, loader.tilewidth, loader.tileheight, TLN_ClonePalette(TLN_GetBitmapPalette(bitmap)));
    pitch = TLN_GetBitmapPitch (bitmap);

    /* load tiles */
    for (id=1, y=0; y<vtiles; y++)
    {
        for (x=0; x<htiles; x++, id++)
        {
            BYTE *srcptr = TLN_GetBitmapPtr (bitmap, loader.margin + x*dx, loader.margin + y*dy);
            TLN_SetTilesetPixels (tileset, id, srcptr, pitch);
        }
    }

    TLN_DeleteBitmap (bitmap);

    return tileset;
}
예제 #3
0
/* loads BMP */
static TLN_Bitmap LoadBMP (char *filename)
{
    BITMAPFILEHEADER bfh;
    BITMAPV5HEADER bv5;
    DWORD StructSize;
    FILE* pf;
    TLN_Bitmap bitmap = NULL;
    unsigned int c;
    int pitch;

    /* open file */
    pf = fopen (filename, "rb");
    if (!pf)
        return NULL;

    /* read BMP header */
    fread (&bfh, sizeof(bfh), 1, pf);
    if (bfh.Type != 0x4D42)
    {
        fclose (pf);
        return NULL;
    }

    /* load info structure */
    memset (&bv5, 0, sizeof(bv5));
    fread (&StructSize, 4, 1, pf);
    fseek (pf, sizeof(bfh), SEEK_SET);
    fread (&bv5, StructSize, 1, pf);

    /* create */
    bitmap = TLN_CreateBitmap (bv5.bV5Width, bv5.bV5Height, bv5.bV5BitCount);
    if (!bitmap)
    {
        fclose (pf);
        return NULL;
    }

    /* load scanlines */
    pitch = TLN_GetBitmapPitch (bitmap);
    fseek (pf, bfh.OffsetData, SEEK_SET);
    for (c=0; c<bv5.bV5Height; c++)
    {
        BYTE* line = TLN_GetBitmapPtr (bitmap, 0, bv5.bV5Height - c - 1);
        fread (line, pitch, 1, pf);
    }

    /* load palette */
    if (bv5.bV5BitCount == 8)
    {
        TLN_Palette palette;

        /* HACK: some editors don't set the bV5ClrUsed field, compute from size */
        if (bv5.bV5ClrUsed == 0)
            bv5.bV5ClrUsed = (bfh.OffsetData - sizeof(bfh) - bv5.bV5Size) / sizeof(RGBQUAD);

        fseek (pf, sizeof(BITMAPFILEHEADER) + bv5.bV5Size, SEEK_SET);
        palette = TLN_CreatePalette (bv5.bV5ClrUsed);
        for (c=0; c<(int)bv5.bV5ClrUsed; c++)
        {
            RGBQUAD color;
            fread (&color, sizeof(RGBQUAD), 1, pf);
            TLN_SetPaletteColor (palette, c, color.r, color.g, color.b);
        }
        TLN_SetBitmapPalette (bitmap, palette);
    }

    fclose (pf);
    return bitmap;
}
예제 #4
0
/*!
 * \brief
 * Loads a spriteset from a png/txt file pair
 * 
 * \param name
 * Base name of the files containing the spriteset
 * 
 * \returns
 * Reference to the newly loaded spriteset or NULL if error
 * 
 * \remarks
 * The spriteset comes in a pair of files called name.png and name.txt. The png file contains
 * the spriteset, whereas the txt contains the coordinates of the rectangles that define individual sprites.
 * These files can be created wit the spritesheet packer tool (http://spritesheetpacker.codeplex.com/)
 * \remarks
 * An associated palette is also created, it can be obtained calling TLN_GetSpritesetPalette()
 */
TLN_Spriteset TLN_LoadSpriteset (const char* name)
{
	FILE *pf;
	char filename[64];
	char line[64];
	int entries = 0;
	TLN_Bitmap bitmap;
	TLN_Spriteset spriteset;
	TLN_Rect *rects, *rect;
	int c;

	/* load png file */
	sprintf (filename, "%s.png", name);
	bitmap = TLN_LoadBitmap (filename);
	if (!bitmap)
		return NULL;

	/* load txt file */
	sprintf (filename, "%s.txt", name);
	pf = FileOpen (filename);
	if (!pf)
	{
		TLN_DeleteBitmap (bitmap);
		TLN_SetLastError (TLN_ERR_FILE_NOT_FOUND);
		return NULL;
	}

	/* count lines */
	while (fgets (line, 64, pf))
		entries++;

	rects = malloc (sizeof(TLN_Rect)*entries);
	if (!rects)
	{
		TLN_DeleteBitmap (bitmap);
		TLN_SetLastError (TLN_ERR_OUT_OF_MEMORY);
		fclose (pf);
		return NULL;
	}

	/* read entries */
	fseek (pf, 0, SEEK_SET);
	for (c=0; c<entries; c++)
	{
		char* equals;
		char imagename[64];

		/* lee linea */
		fgets (line, 64, pf);
		rect = &rects[c];

		/* formato SpriteSheetPacker: name = x y w h */
		equals = strchr (line, '=');
		if (equals != NULL)
		{
			sscanf (line, "%s = %d %d %d %d", imagename, &rect->x, &rect->y, &rect->w, &rect->h);
			continue;
		}

		/* formato Leshy SpriteSheet Tool csv: name,x,y,w,h */
		equals = strchr (line, ',');
		if (equals != NULL)
		{
			char* del = line;
			while (*del)
			{
				if (*del == ',')
					*del = ' ';
				del++;
			}
			sscanf (line, "%s %d %d %d %d", imagename, &rect->x, &rect->y, &rect->w, &rect->h);
			continue;
		}
	}
	fclose (pf);

	/* create */
	spriteset = TLN_CreateSpriteset (
		entries, 
		rects, 
		TLN_GetBitmapPtr (bitmap, 0,0), 
		TLN_GetBitmapWidth (bitmap),
		TLN_GetBitmapHeight (bitmap), 
		TLN_GetBitmapPitch (bitmap), 
		TLN_ClonePalette(TLN_GetBitmapPalette(bitmap))
	);
	
	/* free resources */
	free (rects);
	TLN_DeleteBitmap (bitmap);
	
	if (spriteset)
		TLN_SetLastError (TLN_ERR_OK);
	else
		TLN_SetLastError (TLN_ERR_OUT_OF_MEMORY);
	
	return spriteset;
}